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

mt8*_*t81 4 objective-c ios

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

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

NSString *propertyName = nil;
[invocation getArgument:&propertyName atIndex:3];
Run Code Online (Sandbox Code Playgroud)

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

__unsafe_unretained NSString *propertyName = nil;
[invocation getArgument:&propertyName atIndex:3];
Run Code Online (Sandbox Code Playgroud)

成功了,不错!!但我想知道为什么。谁能解释一下?

eik*_*eik 5

签名-[NSInvocation getArgument:atIndex:]IS

- (void)getArgument:(void *)buffer
        atIndex:(NSInteger)index
Run Code Online (Sandbox Code Playgroud)

所以buffer是无类型的,不一定是对象。ARC 要求您使用非保留的引用(因此是未保留的部分),它不会使被引用的对象保持活动状态并且可以悬挂(因此危险或不安全),因此它必须被限定__unsafe_unretained,另请参阅clang 规范,您不得不告诉ARC不要在意这块内存。

不再真正推荐使用 NSInvocation 了,它不适用于 ARC 并且在 Swift 中不可用。作为替代方案,您可以使用-[NSObject methodForSelector:].