Xcode中Objc动态调用方法同时避免警告的几个办法

我们在Xcode中使用objc写代码的时候往往会碰到动态调用方法的时候.

如果是静态调用这很常见,不会有任何问题:

[self performSelector:@selector(method)];

但如果method是运行时变化的值,则编译器就会发出警告:

简单来说,这是因为编译器在开启ARC后不知道该方法的返回值是什么,该如何处理,是标记为ns_returns_retained还是ns_returns_autoreleased.

在网上搜了一下有几种办法可以解决,首先如果动态调用的方法不返回值,则可以使用afterDelay来消除警告:

[_gameScene.curMapNode performSelector:NSSelectorFromString(selectorName) withObject:nil afterDelay:0];

如果返回值则可以使用宏来消除警告:

#define SuppressPerformSelectorLeakWarning(Stuff) \     do { \         _Pragma("clang diagnostic push") \         _Pragma("clang diagnostic ignored \"-Warc-performSelector-leaks\"") \         Stuff; \         _Pragma("clang diagnostic pop") \     } while (0)

然后在需要的地方用宏包含:

NSString *newCmd;
        SuppressPerformSelectorLeakWarning( newCmd = [_gameScene.curMapNode performSelector:NSSelectorFromString(selectorName)]; );

最后一种方法是使用IMP调用的方式,以下是我写的调用包装器:

-(id)invokeSelectorNamed:(NSString *)selectorName{ SEL selector = NSSelectorFromString(selectorName); IMP imp = [self methodForSelector:selector]; id (*func)(id,SEL) = (void*)imp; return func(_gameScene.curMapNode,selector); }

注意方法返回的是id,意味着可以是任何Objc的对象值,但你必须时刻清楚实际返回值的类型:

NSString *newCmd = [_gameScene.curMapNode invokeSelectorNamed:selectorName];

这里我知道返回的值实际是NSString类型,所以没有问题.

你可能感兴趣的:(xcode,警告,动态调用)