这段代码用于在非 ARC 中正常编译:
int *privateObjMemory = (int *)[myObject performSelector:@selector(privateMethod)];
现在我在 ARC 我得到:
ARC 不允许将 Objective-C 指针转换为“int *”
我该如何解决这个问题?:)
这段代码用于在非 ARC 中正常编译:
int *privateObjMemory = (int *)[myObject performSelector:@selector(privateMethod)];
现在我在 ARC 我得到:
ARC 不允许将 Objective-C 指针转换为“int *”
我该如何解决这个问题?:)
写成:
int* privateObjMemory = [myObject privateMethod];
;)
您要避免这种情况的原因是它对 ARC 模棱两可。performSelector:
返回一个对象——应该int*
保留它吗?嗯……不。
更新
基于评论,并删除以前的写作:
但这不是一个很好的解决方案。如果您正在调用特定的私有 API,那么您必须知道它的签名(例如参数和返回类型)。如果它是您的私有 API,那么想办法让该私有接口有选择地可见。
如果是其他人的私有 API,则在具有正确参数和返回类型的类型上声明一个类别。
然后选择器被正确声明,编译器将能够通过直接向对象发送消息来正确设置调用——无需使用performSelector:
.
不要将 Obj-C 指针转换为int *
,如果使用 ARC,则无法解决此问题。
之所以采用这种方式,是因为int*
在运行时将 ponter 转换为意味着无法跟踪指针指向的对象的内存。因此,在不使用 ARC 时允许这样做(因为您可以自己管理内存),但在 ARC 处于活动状态时则不允许。
如果您必须这样做,那么您可以在使用它的文件上禁用 ARC。-fno-objc-arc
在项目设置中使用实现文件上的编译器标志。
我不认为这真的与ARC有关。ARC 只会导致警告或错误。AFAIK(我没有用血签名)使用 performSelector 调用的方法的返回值是 nil 或 id。因此它必须是一个对象而不是一个 skalar。它可以很好地与 int* 一起使用,因为 id 是对(但对对象,而不是对标量)的引用。为了节省开支,您应该更改代码并返回一个 NSNubmer 对象。
用于id
对象的类型。
在 ARC文档中,他们特别说..
id 和 void * 之间没有随意转换。
performSelector
返回 anid
并且不能使用非目标 C 对象引用进行强制转换。
在我链接的文档中,向下滚动并阅读“管理免费桥接”部分。