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

来源:互联网 发布:跳舞软件 编辑:程序博客网 时间:2024/06/16 06:45

我们在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类型,所以没有问题.

0 0