From 99d4f9ea0cd7927570d998e17611a19666df41b9 Mon Sep 17 00:00:00 2001 From: Yavor Georgiev Date: Wed, 10 Feb 2016 18:19:04 +0200 Subject: [PATCH] Replace -[NSObject performSelector:] with NSInvocation It appears that `-[NSObject performSelector:]` returns a dummy value when calling a void method on the iOS Simulator, whereas it correctly returns `nil` on a device. Since `-[NSObject performSelector:]` is declared as returning `id`, the iOS runtime tries to marshal the dummy value to a JavaScript object and fails because the dummy value is not a valid Objective-C object. The fix is to use `-[NSObject valueForKey:]` for non-void zero-parameter methods and `NSInvocation` for everything else. --- ui/transition/transition.ios.ts | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/ui/transition/transition.ios.ts b/ui/transition/transition.ios.ts index 24b7d5909..3cecea868 100644 --- a/ui/transition/transition.ios.ts +++ b/ui/transition/transition.ios.ts @@ -3,6 +3,18 @@ import frame = require("ui/frame"); import types = require("utils/types"); import trace = require("trace"); +module UIViewControllerAnimatedTransitioningMethods { + let methodSignature = NSMethodSignature.signatureWithObjCTypes("v@:c"); + let invocation = NSInvocation.invocationWithMethodSignature(methodSignature); + invocation.selector = "completeTransition:"; + + export function completeTransition(didComplete: boolean) { + let didCompleteReference = new interop.Reference(interop.types.bool, didComplete); + invocation.setArgumentAtIndex(didCompleteReference, 2); + invocation.invokeWithTarget(this); + } +} + class AnimatedTransitioning extends NSObject implements UIViewControllerAnimatedTransitioning { public static ObjCProtocols = [UIViewControllerAnimatedTransitioning]; @@ -22,10 +34,8 @@ class AnimatedTransitioning extends NSObject implements UIViewControllerAnimated } public animateTransition(transitionContext: any): void { - let containerView = transitionContext.performSelector("containerView"); - var completion = (finished: boolean) => { - transitionContext.performSelectorWithObject("completeTransition:", finished); - } + let containerView = transitionContext.valueForKey("containerView"); + var completion = UIViewControllerAnimatedTransitioningMethods.completeTransition.bind(transitionContext); switch (this._operation) { case UINavigationControllerOperation.UINavigationControllerOperationPush: this._transitionType = "push"; break; case UINavigationControllerOperation.UINavigationControllerOperationPop: this._transitionType = "pop"; break;