Error compiling with ARC when runtime programming dynamic method

自闭症网瘾萝莉.ら 提交于 2019-11-29 02:38:36

In your call

NSLog(@"How are you , %@", [Test dynamic]);

the ARC compiler does not know the return type of the method. But ARC needs to know if the method returns an object to add the appropriate retain/release calls for managing the lifetime.

Even without ARC you get a compiler warning

class method '+dynamic' not found (return type defaults to 'id')

but the ARC compiler is more strict.

You can call

NSLog(@"How are you , %@", [[Test class] performSelector:@selector(dynamic)]);

because performSelector returns an id. For functions returning anything other than an object you can use NSInvocation.

Alternatively, you can declare the dynamic method using a Class Extension:

@interface Test (DynamicMethods)
+ (NSString *)dynamic;
@end

ARC has definitely thrown a wrench into some of the fun runtime method resolution machinery. There are still a few options, however. Equally as ugly as the performSelector: technique you mentioned is an explicit objc_msgSend() function call. The function needs to be cast with its return and argument types, like so:

(void (*)(id, SEL)objc_msgSend)([Test class], @selector(dynamic)));

(You'll now get a warning about implicit declaration; just declare extern id objc_msgSend(id, SEL, ...); somewhere.)

A better option is to cast the object to id when you make the message send (or store it in an id variable to begin with). The compiler never knows anything about the messages that ids respond to, so it can't and doesn't complain about sending arbitrary messages. You can cast a class object to id just as you can an instance.

[(id)Test dynamic];

or

[(id)testInstance anotherDynamicName];
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!