Bug 13518 - Unable to cast object of type error from within selector viewDidAppear
Summary: Unable to cast object of type error from within selector viewDidAppear
Status: RESOLVED FIXED
Alias: None
Product: iOS
Classification: Xamarin
Component: General ()
Version: 6.4.0
Hardware: Macintosh Mac OS
: --- normal
Target Milestone: Untriaged
Assignee: Bugzilla
URL:
: 13724 ()
Depends on:
Blocks:
 
Reported: 2013-07-26 13:12 UTC by dj_technohead
Modified: 2013-08-06 13:13 UTC (History)
7 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED FIXED

Description dj_technohead 2013-07-26 13:12:42 UTC
After updating Xamarin.iOS from 6.2.7 to 6.4 I started to see crashes in a Monocross app on the physical device only. Looking in my log files I see the following:

 Unable to cast object of type 'Mediscripts.Touch.NewRxView' (Objective-C type: 'Mediscripts.Touch.NewRxView') to type 'Mediscripts.Touch.BaseMXTouchViewController`1[MediScriptsEngine.Models.Md]'.
   Additional information:
       Selector: viewDidAppear:
       Method: Mediscripts.Touch.BaseMXTouchViewController`1<MediScriptsEngine.Models.Md>:ViewDidAppear (bool)
   
     at (wrapper managed-to-native) MonoTouch.UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr)
     at MonoTouch.UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x0004c] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:38 
     at Mediscripts.Touch.Application.Main (System.String[] args) [0x00030] in /Users/dj_technohead/Projects/Mediscripts/trunk/Mobile/Touch/Mediscripts.Touch/Main.cs:32 

Running in the simulator is fine. Reverting the Xamarin install to 6.2.7 fixes the crashes. 

thanks,
Dennis
Comment 1 Rolf Bjarne Kvinge [MSFT] 2013-07-29 18:51:46 UTC
This is a new type check introduced in Xamarin.iOS 6.4, to prevent a very hard to track down bug in your code.

In this particular case you have an Objective-C object of the Mediascripts.Touch.NewRxView type, and then trying to convert it to a Mediascripts.Touch.BaseMXTouchViewController instance.

Still I'd like to have a look at your code to see how you ended up in this situation, so would it be possible to add a test project?
Comment 2 dj_technohead 2013-07-29 19:46:12 UTC
Hi Rolf,
   I'm not doing anything special here. I have a form of type NewRxView which descends from BaseMXTouchViewController. Note that I'm using the naming conventions from Monocross... where the view is really a viewcontroller.


public class NewRxView : BaseMXTouchViewController<NewRx>

   It should be perfectly legitimate to reference an instance of NewRxView as a BaseMXTouchViewController. However, I looked through my code and did not see any place where I cast it as such.

Dennis
Comment 3 Rolf Bjarne Kvinge [MSFT] 2013-07-29 19:48:30 UTC
Dennis, can you create a test project I can use to test this for myself?
Comment 4 dj_technohead 2013-07-29 19:50:59 UTC
Ok, will do as soon as a I can.

Dennis
Comment 6 Andrew 2013-07-30 07:15:19 UTC
Hi, I got same problem after updating Xamarin.iOS. It appears when calling methods of a class with generic parameters.
My error identical to one reported by the topic starter:

=====================================================================================
Message: 
Unable to cast object of type 'ttt.Client.IOs.Forms.ActionsDataSource' (Objective-C type: 'ttt.Client.IOs.Forms.ActionsDataSource') to type 'ttt.Client.IOs.SimpleTableViewSource`1[ttt.Client.Ui.Portal.IPortalTabItem]'.
Additional information:
	Selector: numberOfSectionsInTableView:
	Method: ttt.Client.IOs.SimpleTableViewSource`1<ttt.Client.Ui.Portal.IPortalTabItem>:NumberOfSections (MonoTouch.UIKit.UITableView)


Exception: System.InvalidCastException
Trace:
  at (wrapper managed-to-native) MonoTouch.UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr)
  at MonoTouch.UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x0004c] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:38 
  at ttt.Client.IOsClient.Application.Main (System.String[] args) [0x000bf] in /Volumes/tttMain/Sources/Client/ttt.IOs.Application/Main.cs:45 
=====================================================================================


I got similar issue in another place of my code, the DatetimeControl is an inheritor of BaseViewControl<Datetime?>, note that it was tried to be casted to BaseViewControl<string> instead:

------ Exception Details------
Message: 
Unable to cast object of type 'zzz.Client.IOs.Forms.Controls.DatetimeControl' (Objective-C type: 'zzz.Client.IOs.Forms.Controls.DatetimeControl') to type 'zzz.Client.IOs.Forms.Controls.BaseViewControl`1[System.String]'.
Additional information:
	Selector: layoutSubviews
	Method: zzz.Client.IOs.Forms.Controls.BaseViewControl`1<string>:LayoutSubviews ()


Exception: System.InvalidCastException
Trace:
  at (wrapper managed-to-native) MonoTouch.UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr)
  at MonoTouch.UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x0004c] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:38 
  at zzz.Client.IOsClient.Application.Main (System.String[] args) [0x000bf] in /Volumes/zzzMain/Sources/Client/zzz.IOs.Application/Main.cs:45 
=====================================================================================

I was able to temporary fix it by removing generic parameter of BaseViewControl (inlined the parameter down by hierarchy). Looks like something is definitely broken with recent Xamarin update.



Xamarin.iOS
Version: 6.4.0.2 (Business Edition)
Hash: c9f7659
Branch: 
Build date: 2013-18-07 21:36:03-0400

Xamarin Studio
Version 4.0.10 (build 7)

Runtime:
	Mono 3.2.0 ((no/7c7fcc7)
	GTK 2.24.20
	GTK# (2.12.0.0)
	Package version: 302000000
Comment 7 Rolf Bjarne Kvinge [MSFT] 2013-07-30 09:24:24 UTC
This is a result of using an unsupported "feature": generic subclasses of NSObject.

In fact this shows fairly well how things can break in strange ways with generic NSObject subclasses: Xamarin.iOS complains that it can't convert from 'Mediscripts.Touch.NewRxView' to 'Mediscripts.Touch.BaseMXTouchViewController`1[MediScriptsEngine.Models.Md]' - which is correct, since there is no valid conversion between those two types (NewRXView inherits from BaseMXTouchViewController with a different generic type argument). Yet it's wrong because Xamarin.iOS shouldn't try to convert to that particular base type instantiation in the first place (and without the type check you end up violating the type safety of C# - which is the reason generic NSObject subclasses is an unsupported "feature").

Workarounds:
* For debug builds you can add --registrar:olddynamic to the additional mtouch arguments.
* For release builds you don't have to do anything, since the invalid cast check is not present in release builds.

In any case I've fixed Xamarin.iOS to do this type check for the time being.

monotouch/master-3.0: 1eaa95db6002fab098eb5fc7e95142840fbdffbc
monotouch/monotouch-6.4-series: 21c02aa7b76ec00262915c88aff4f95d8b647a1a
Comment 8 Rolf Bjarne Kvinge [MSFT] 2013-07-30 09:25:10 UTC
Correction: I've fixed Xamarin.iOS to *not* do this type check for the time begin.
Comment 9 dj_technohead 2013-07-30 13:39:44 UTC
Thanks Rolf. So does this mean that Xamarin.iOS will do this type checking in the future? If so, will there be a way to turn it off?
Comment 10 Rolf Bjarne Kvinge [MSFT] 2013-07-30 13:47:58 UTC
I'm working on making it possible to use generic NSObject subclasses. The type check will be added back when that work is completed.
Comment 11 Rolf Bjarne Kvinge [MSFT] 2013-08-02 21:25:18 UTC
*** Bug 13724 has been marked as a duplicate of this bug. ***
Comment 12 GouriKumari 2013-08-06 13:13:23 UTC
Retested.

Expected Result:
The App should not produce any crash on device

Actual Result:
App launches and works successfully on device without any crash. 

Supplemental Info:
Deploy to Device Output: https://gist.github.com/GouriKumari/fb1377f63ddef3033d40

Test Env:
Xamarin Studio
Version 4.0.10 (build 7)
Installation UUID: fafd3486-1aec-4f9c-ab77-08bf4a000708
Runtime:
	Mono 3.2.2 ((no/4a17166)
	GTK 2.24.20
	GTK# (2.12.0.0)
	Package version: 302020000

Apple Developer Tools
Xcode 4.6.3 (2068)
Build 4H1503

Xamarin.Mac
Xamarin.Mac: 1.4.8

Xamarin.iOS
Version: 6.4.1.14 (Trial Edition)
Hash: 1c428d5
Branch: 
Build date: 2013-06-08 05:38:40-0400