Bug 2441 - InvalidCastException in CALayer.ActionForKey(System.String eventKey)
Summary: InvalidCastException in CALayer.ActionForKey(System.String eventKey)
Status: RESOLVED FIXED
Alias: None
Product: iOS
Classification: Xamarin
Component: Xamarin.iOS.dll ()
Version: 5.0
Hardware: Macintosh Mac OS
: --- normal
Target Milestone: Untriaged
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2011-12-09 14:34 UTC by Jon Lipsky
Modified: 2011-12-19 16:03 UTC (History)
3 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 Jon Lipsky 2011-12-09 14:34:16 UTC
I'm receiving the following exception when I try to override the "ActionForKey" method in the CALayer class.  Specifically, I get this exception when calling "base.ActionForKey(eventKey)".


[FATAL] Unable to cast object of type 'MonoTouch.CoreAnimation.CABasicAnimation' to type 'MonoTouch.CoreAnimation.CAAction'.
System.InvalidCastException: Unable to cast object of type 'MonoTouch.CoreAnimation.CABasicAnimation' to type 'MonoTouch.CoreAnimation.CAAction'.
  at MonoTouch.CoreAnimation.CALayer.ActionForKey (System.String eventKey) [0x00049] in /Developer/MonoTouch/Source/monotouch/src/CoreAnimation/CALayer.g.cs:601
Comment 1 Rolf Bjarne Kvinge [MSFT] 2011-12-09 19:07:58 UTC
According to Apple's documentation the return value for actionForKey: must implement the CAAction protocol. CABasicAnimation does implement the CAAction protocol, but the managed CABasicAnimation class doesn't (and can't) inherit from the (managed) CAAction class. This means that this exception is thrown when managed code tries to cast the returned CABasicAnimation instance to CAAction.

In short: ActionForKey's return type is wrong, it should be declared as NSObject, since it can actually be any object. Unfortunately this is a breaking change.

Miguel: how can this best be solved? ActionForKey is apparently unusable as it is, so I think this breaking change should be ok.
Comment 2 Miguel de Icaza [MSFT] 2011-12-09 22:01:19 UTC
Agreed, we need to change the return to be NSObject and deal with it that way.
Comment 3 Rolf Bjarne Kvinge [MSFT] 2011-12-12 18:06:39 UTC
Jon, do you have some sample code I can use to create a test case out of?
Comment 4 Jon Lipsky 2011-12-12 18:35:39 UTC
Here's the test class I created to test this on my machine:

public class TestLayer : CALayer
    {        
    	public bool AnimationsEnabled {get;set;}
    	
        public TestLayer () : base()
        {
        	AnimationsEnabled = true;    
        }
        
        public override CAAction ActionForKey (string eventKey)
        {
            if (AnimationsEnabled)
            {
            	return base.ActionForKey(eventKey);
            }
            return null;
        }
        
        public override void DrawInContext (CGContext ctx)
        {
            // Do anything here with the context  
        }
    }

I just added an instance of that layer to a UIView and called "SetNeedsDisplay()"
Comment 5 Rolf Bjarne Kvinge [MSFT] 2011-12-15 09:55:19 UTC
Fixes committed (maccore/f997c11). I also found a few more properties using CAAction which I also fixed. This will be included in the next beta (5.1.2).

In the meantime you can use this as a workaround:

[Export ("actionForKey:")]
public new NSObject ActionForKey (string eventKey)
{
  return Runtime.GetNSObject (Messaging.IntPtr_objc_msgSendSuper_IntPtr (SuperHandle, new Selector ("actionForKey:").Handle, new NSString (eventKey).Handle));
}

Note that the fixes will change the signature of ActionForKey, so you'll get a compiler error with the current ActionForKey overload once you upgrade.

Thanks for the test case!