为什么缓冲区需要在NSInvocation上__unsafe_unretained - getArgument:atIndex:?

时间:2015-10-29 19:24:48

标签: ios objective-c

我正在使用NSInvocation并需要从中检索其中一个属性。

我使用的是以下代码,但我有一些奇怪的行为,调用[invocation invoke];

NSString *propertyName = nil;
[invocation getArgument:&propertyName atIndex:3];

我读到为了使其在ARC下运行,我们需要使用__unsafe_unretained

__unsafe_unretained NSString *propertyName = nil;
[invocation getArgument:&propertyName atIndex:3];

工作得很好!!但我想了解原因。谁能解释一下呢?

2 个答案:

答案 0 :(得分:3)

-[NSInvocation getArgument:atIndex:]的{​​{3}}是

- (void)getArgument:(void *)buffer
        atIndex:(NSInteger)index

所以buffer是无类型的,不一定是对象。 ARC要求您使用非保留引用(因此未保留部分),这不会使引用的对象保持活动并且可以悬挂(因此危险或不安全),因此它必须是signature __unsafe_unretained,另见qualified,你必须告诉ARC不要关心这段记忆。

不再推荐使用NSInvocation,它不适用于ARC,并且在Swift中不可用。作为替代方案,您可以使用clang specification

答案 1 :(得分:0)

问题是,谁负责修改对象的保留计数(如果它甚至是对象)。我认为它也被称为所有者。

我们可以试着说,任何人都应该这样做。但NSInvocation缺乏这方面的知识。它不知道你是否传递__strong或__weak,而且它不必。这意味着在分配值时,调用不知道是否实际保留对象,因为它不知道对象是否将被释放。然后,该责任将发送给呼叫者。

而且,我想说,内存管理应始终由调用者管理。

例如,与NSError的区别在于NSError可能被调用的函数分配,这就是参数需要__autorelease的原因。这不是NSInvocation的情况。