使用NSInvocation在主线程上执行选择器

kpo*_*wer 2 iphone animation objective-c nsinvocation

我想在主线程上执行动画(导致UIKit对象不是线程安全的),但是在一些单独的线程中准备它.我有(baAnimation - 之前已经分配了CABasicAnimation):

SEL animationSelector = @selector(addAnimation:forKey:);
NSString *keyString = @"someViewAnimation";

NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[workView.layer methodSignatureForSelector:animationSelector]];
[inv setTarget:workView.layer];
[inv setSelector:animationSelector];
[inv setArgument:baAnimation atIndex:2];
[inv setArgument:keyString atIndex:3];
[inv performSelectorOnMainThread:@selector(invoke) withObject:nil waitUntilDone:NO];
Run Code Online (Sandbox Code Playgroud)

我明白了:

*** + [NSCFString length]:无法识别的选择器发送到类0x1fb36a0

呼叫:

>     #0 0x020984e6 in objc_exception_throw
>     #1 0x01f7e8fb in +[NSObject doesNotRecognizeSelector:]
>     #2 0x01f15676 in ___forwarding___
>     #3 0x01ef16c2 in __forwarding_prep_0___
>     #4 0x01bb3c21 in -[CALayer addAnimation:forKey:]
>     #5 0x01ef172d in __invoking___
>     #6 0x01ef1618 in -[NSInvocation invoke]
Run Code Online (Sandbox Code Playgroud)

[workView.layer addAnimation:baAnimation forKey:@"someViewAnimation"];工作正常.我究竟做错了什么?

hen*_*nes 6

除了[inv retainArguments](如Chris Suter所述)之外,您还需要将参数作为指向底层内存的指针传递.引用API:

"当参数值是对象时,将指针传递给应从中复制对象的变量(或内存):

NSArray *anArray;  
[invocation setArgument:&anArray atIndex:3];  
Run Code Online (Sandbox Code Playgroud)

"

  • 这应该是公认的正确答案,因为这是一个更大的问题(根本没有传递正确的东西,而不是内存管理问题) (3认同)