ARC [rewriter] NSInvocation's setArgument is not safe to be used with an object with ownership other than __unsafe_unretained

StackOverflow https://stackoverflow.com/questions/12530596

Question

I been to convert my project to ARC and i m stuck with this error.

&object,&invocation and &callerToRetain is showing me error of "[rewriter] NSInvocation's setArgument is not safe to be used with an object with ownership other than __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]];
}}

Please help me out.

Was it helpful?

Solution

An NSInvocation by default does not retain or copy given arguments for efficiency, so each object passed as argument must still live when the invocation is invoked. That means the pointers passed to -setArgument:atIndex: are handled as __unsafe_unretained.

If you use NSInvocation in ARC, the simplest way to get it working is

  1. call [invocation retainArguments] after creating the invocation object. That means the invocation will retain the given arguments.
  2. When passing the arguments, cast them to __unsafe_unretained.
  3. There is no step 3.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top