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

后端 未结 6 762
离开以前
离开以前 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条回答
  •  执笔经年
    2020-12-25 12:47

    This is a complete guess, but might it be something to do with the argument being passed in by reference as a void*?

    In the case you've mentioned, this doesn't really seem a problem, but if you were to call, eg. getArgument:atIndex: then the compiler wouldn't have any way of knowing whether the returned argument needed to be retained.

    From NSInvocation.h:

    - (void)getArgument:(void *)argumentLocation atIndex:(NSInteger)idx;
    - (void)setArgument:(void *)argumentLocation atIndex:(NSInteger)idx;
    

    Given that the compiler doesn't know whether the method will return by reference or not (these two method declarations have identical types and attributes), perhaps the migrator is being (sensibly) cautious and telling you to avoid void pointers to strong pointers?

    Eg:

    NSDecimalNumber* val;
    [anInvocation getArgument:&val atIndex:2];
    anInvocation = nil;
    NSLog(@"%@", val); // kaboom!
    
    
    __unsafe_unretained NSDecimalNumber* tempVal;
    [anInvocation getArgument:&tempVal atIndex:2];
    NSDecimalNumber* val = tempVal;
    anInvocation = nil;
    NSLog(@"%@", val); // fine
    

提交回复
热议问题