ARC [rewriter] NSInvocation的setArgument与不具有__unsafe_unretained的所有权的对象一起使用是不安全的

Bul*_*lla 1 nsinvocation automatic-ref-counting

我一直把我的项目转换成ARC,我坚持这个错误.

与对象,与调用和&callerToRetain正显示出我的错误"[重写] 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]];
}}
Run Code Online (Sandbox Code Playgroud)

请帮帮我.

Tam*_*ese 5

NSInvocation默认情况下,不保留或复制给定参数的效率,所以调用调用时,作为参数传递的每个对象都必须仍住.这意味着传递给-setArgument:atIndex:的指针被处理为__unsafe_unretained.

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

  1. 调用[invocation retainArguments]创建调用对象之后.这意味着调用将保留给定的参数.
  2. 传递参数时,将它们转换为__unsafe_unretained.
  3. 没有第3步.