【发布时间】:2012-01-14 09:34:27
【问题描述】:
我有一个返回 CGSize 的类方法,我想通过 Objective-C 运行时函数调用它,因为我将类和方法名称作为字符串值。
我在 XCode 4.2 中使用 ARC 标志进行编译。
方法签名:
+(CGSize)contentSize:(NSString *)text;
我尝试的第一件事是使用objc_msgSend 调用它,如下所示:
Class clazz = NSClassFromString(@"someClassName);
SEL method = NSSelectorFromString(@"contentSize:");
id result = objc_msgSend(clazz, method, text);
这会因“EXC_BAD_ACCESS”而崩溃,并且没有堆栈跟踪。我首先使用它是因为objc_msgSend 的文档说,
当遇到方法调用时,编译器会生成对函数
objc_msgSend、objc_msgSend_stret、objc_msgSendSuper或objc_msgSendSuper_stret之一的调用。 [...] 将数据结构作为返回值的方法使用objc_msgSendSuper_stret和objc_msgSend_stret发送。
接下来,我像这样使用objc_msgSend_stret:
Class clazz = NSClassFromString(@"someClassName);
SEL method = NSSelectorFromString(@"contentSize:");
CGSize size = CGSizeMake(0, 0);
objc_msgSend_stret(&size, clazz, method, text);
使用上面的签名会给我以下两个编译器错误和两个警告:
错误:自动引用计数问题:ARC 不允许将非 Objective-C 指针类型“CGSize *”(又名“struct CGSize *”)隐式转换为“id”
警告:语义问题:不兼容的指针类型将“CGSize *”(又名“struct CGSize *”)传递给“id”类型的参数
错误:自动引用计数问题:ARC 不允许将 Objective-C 指针隐式转换为“SEL”
警告:语义问题:不兼容的指针类型传递 '__unsafe_unretained Class' 到 'SEL' 类型的参数
如果我看方法的声明,它是:
OBJC_EXPORT void objc_msgSend_stret(id self, SEL op, ...)
__OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
等同于objc_msgSend:
OBJC_EXPORT id objc_msgSend(id self, SEL op, ...)
__OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
这向我解释了编译器错误,但我在运行时使用什么来在运行时调用类及其静态方法并返回结构值?
【问题讨论】:
标签: objective-c struct automatic-ref-counting objective-c-runtime class-method