1

我一直在将我的项目转换为 ARC,但我遇到了这个错误。

&object,&invocation 和 &callerToRetain 向我显示错误“[rewriter] NSInvocation 的 setArgument 不能安全地用于拥有除 __unsafe_unretained 之外的所有权的对象”

+ (void)performSelector:(SEL)selector onTarget:(id *)target withObject:(id)object amount:(void *)amount callerToRetain:(id)callerToRetain{if ([*target respondsToSelector:selector]) {
    NSMethodSignature *signature = nil;
    signature = [*target methodSignatureForSelector:selector];
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];

    [invocation setSelector:selector];

    int argumentNumber = 2;

    // If we got an object parameter, we pass a pointer to the object pointer
    if (object) {
        [invocation setArgument:&object atIndex:argumentNumber];
        argumentNumber++;
    }

    // For the amount we'll just pass the pointer directly so NSInvocation will call the method using the number itself rather than a pointer to it
    if (amount) {
        [invocation setArgument:amount atIndex:argumentNumber];
    }

    SEL callback = @selector(performInvocation:onTarget:releasingObject:);
    NSMethodSignature *cbSignature = [ASIHTTPRequest methodSignatureForSelector:callback];
    NSInvocation *cbInvocation = [NSInvocation invocationWithMethodSignature:cbSignature];
    [cbInvocation setSelector:callback];
    [cbInvocation setTarget:self];
    [cbInvocation setArgument:&invocation atIndex:2];
    [cbInvocation setArgument:&target atIndex:3];
    if (callerToRetain) {
        [cbInvocation setArgument:&callerToRetain atIndex:4];
    }

    CFRetain(invocation);

    // Used to pass in a request that we must retain until after the call
    // We're using CFRetain rather than [callerToRetain retain] so things to avoid earthquakes when using garbage collection
    if (callerToRetain) {
        CFRetain(callerToRetain);
    }
    [cbInvocation performSelectorOnMainThread:@selector(invoke) withObject:nil waitUntilDone:[NSThread isMainThread]];
}}

请帮帮我。

4

1 回答 1

5

NSInvocation为了提高效率,默认情况下不保留或复制给定的参数,因此作为参数传递的每个对象在调用调用时必须仍然存在。这意味着传递给 -setArgument:atIndex: 的指针作为 __unsafe_unretained 处理。

如果你NSInvocation在 ARC 中使用,让它工作的最简单方法是

  1. 创建调用[invocation retainArguments]对象后调用。这意味着调用将保留给定的参数。
  2. 传递参数时,将它们转换为__unsafe_unretained.
  3. 没有第 3 步。
于 2013-04-23T14:00:23.893 回答