J'ai été à la migration d'un bloc de code automatique de comptage de référence (ARC), et a l'ARC migrator jeter l'erreur
NSInvocation de setArgument n'est pas sûr pour être utilisé avec un objet avec la propriété autres que les __dangereuse_consignes
sur de code où j'avais attribué un objet en utilisant quelque chose comme
NSDecimalNumber *testNumber1 = [[NSDecimalNumber alloc] initWithString:@"1.0"];
puis le définir comme un NSInvocation argument à l'aide de
[theInvocation setArgument:&testNumber1 atIndex:2];
Pourquoi est-il vous empêche de le faire? Il semble juste comme de la mauvaise utilisation de __unsafe_unretained
objets comme arguments. Par exemple, le code suivant provoque un accident en vertu de l'ARC:
NSDecimalNumber *testNumber1 = [[NSDecimalNumber alloc] initWithString:@"1.0"];
NSMutableArray *testArray = [[NSMutableArray alloc] init];
__unsafe_unretained NSDecimalNumber *tempNumber = testNumber1;
NSLog(@"Array count before invocation: %ld", [testArray count]);
// [testArray addObject:testNumber1];
SEL theSelector = @selector(addObject:);
NSMethodSignature *sig = [testArray methodSignatureForSelector:theSelector];
NSInvocation *theInvocation = [NSInvocation invocationWithMethodSignature:sig];
[theInvocation setTarget:testArray];
[theInvocation setSelector:theSelector];
[theInvocation setArgument:&tempNumber atIndex:2];
// [theInvocation retainArguments];
// Let's say we don't use this invocation until after the original pointer is gone
testNumber1 = nil;
[theInvocation invoke];
theInvocation = nil;
NSLog(@"Array count after invocation: %ld", [testArray count]);
testArray = nil;
en raison de la overrelease d' testNumber1
, parce que le temporaire __unsafe_unretained
tempNumber
variable n'est pas la conserver après l'original pointeur est défini à l' nil
(simulation d'un cas où l'invocation est utilisé après la référence initiale à un argument a disparu). Si l' -retainArguments
ligne est sans commentaire (provoquant l'NSInvocation pour tenir à l'argument), ce code ne plante pas.
Exactement le même incident se produit si j'utilise testNumber1
directement comme argument d' -setArgument:
, et il est également résolu si vous utilisez -retainArguments
. Pourquoi, alors, ne l'ARC migrator dire que l'utilisation fermement pointeur comme un argument de NSInvocation de l' -setArgument:
est dangereux, sauf si vous utilisez quelque chose, c'est - __unsafe_unretained
?