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.
This commit is contained in:
Yavor Georgiev
2016-02-10 18:19:04 +02:00
parent c1edaaca29
commit 99d4f9ea0c

View File

@ -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;