[不重复:仔细阅读问题和已经给出的答案,我已经阅读过]
我正面临这个问题,我需要替换-performSelector
方法,因为它会在带有 ARC 的编译器中引起该警告
performSelector 可能会导致泄漏,因为它的选择器是未知的
我知道关于该主题有不同的问题:
而且我也知道避免该警告的技术。
有时作为一种解决方案,我发现最建议的建议是使用dispatch_async(dispatch_get_main_queue(),^(void) { WHATEVER });
,但据我所知,调度需要在下一个运行循环中执行块,-performSelector
(没有延迟)立即执行。
为什么要进行这种精神自慰?想象一下,您正在使用新的 Gamekit 方法进行身份验证,game kit 可以在 auth 块内部向您发送一个视图控制器,以使用户进行一些操作(例如创建 id、登录等)。如果他/她想要查看该视图控制器,警告用户可能很有用。为此,我正在编写一个协议。特别是该方法应该返回一个 BOOL - (BOOL)shouldLoadGameKitViewController: (UIViewController*) viewController;
,我想使用它来调用它-performSelector
. 重点是,如果方法没有立即返回,我就无法从代表那里得到答案。
我正在使用 NSInvocation 来实现这一点,但是很冗长,是否存在其他方式?
[使用代码更新]
请注意,现在我正在使用调用,线程检查部分仍未实现。评论有给出警告的部分
- (void) dispatchToDelegate: (SEL) selector withArg: (id) arg error: (NSError*) err
{
NSMethodSignature *methodSig = [[self class] instanceMethodSignatureForSelector:selector];
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSig];
[invocation setTarget:self.delegate];
if([self.delegate respondsToSelector: selector])
{
if(arg != NULL) {
[invocation setArgument:&arg atIndex:2];
[invocation setArgument:&err atIndex:3];
// [_delegate performSelector: selector withObject: arg withObject: err];
}else {
[invocation setArgument:&err atIndex:2];
// [_delegate performSelector: selector withObject: err];
}
[invocation invoke];
}
else
DLog(@"Method not implemented in the delegate");
}
[某种解决方案仍未测试]
- (BOOL) dispatchToDelegate: (SEL) selector withArg: (id) arg error: (NSError*) err
{
NSMethodSignature *methodSig = [[self class] instanceMethodSignatureForSelector:selector];
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSig];
[invocation setTarget:self.delegate];
BOOL result = NO;
if([self.delegate respondsToSelector: selector])
{
if(arg != NULL) {
[invocation setArgument:&arg atIndex:2];
[invocation setArgument:&err atIndex:3];
// [_delegate performSelector: selector withObject: arg withObject: err];
}else {
[invocation setArgument:&err atIndex:2];
// [_delegate performSelector: selector withObject: err];
}
if ([NSThread isMainThread]) {
[invocation invoke];
}
else{
[invocation performSelectorOnMainThread:@selector(invoke) withObject:nil waitUntilDone:YES];
}
[invocation getReturnValue:&result];
}
else
NSLog(@"Missed Method");
return result;
}
使用 NSMethodSignature 方法,可以加速,并要求返回类型。我仍然没有测试,但它应该成功了。