Why does the ARC migrator say that NSInvocation's -setArgument: is not safe unless the argument is __unsafe_unretained?

后端 未结 6 760
离开以前
离开以前 2020-12-25 12:07

I was migrating a block of code to automatic reference counting (ARC), and had the ARC migrator throw the error

NSInvocation\'s setArgument is not sa

6条回答
  •  -上瘾入骨i
    2020-12-25 12:56

    The important thing here is the standard behaviour of NSInvocation: By default, arguments are not retained and C string arguments are not being copied. Therefore under ARC your code can behave as follows:

    // Creating the testNumber
    NSDecimalNumber *testNumber1 = [[NSDecimalNumber alloc] initWithString:@"1.0"];
    
    // Set the number as argument
    [theInvocation setArgument:&testNumber1 atIndex:2];
    
    // At this point ARC can/will deallocate testNumber1, 
    // since NSInvocation does not retain the argument
    // and we don't reference testNumber1 anymore
    
    // Calling the retainArguments method happens too late.
    [theInvocation retainArguments];
    
    // This will most likely result in a bad access since the invocation references an invalid pointer or nil
    [theInvocation invoke];
    

    Therefore the migrator tells you: At this point you have to explicitly ensure that your object is being retained long enough. Therefore create an unsafe_unretained variable (where you have to keep in mind that ARC won't manage it for you).

提交回复
热议问题