번호
이미지,이 같은 일을 수행해야합니다
for (/*every arguments*/) {
if (/*arg is object. i.e. @encode(arg) is '@'*/) {
if ([arg isKindOfClss:[NSBlock class]]) {
arg = [arg copy]; // copy block
} else {
[arg retain];
}
}
}
을 문제가를 복사하는 동안 arg
이 변경되었을 것입니다 이는 retainArguments
을 호출하면 NSInvocation
의 인수가 변경 될 수 있기 때문에 발생하지 않아야합니다. 이것은 이미 만들어진 많은 가정을 깨뜨릴 것입니다.
업데이트 (인수가 NSInvocation
을 만드는 데 사용되는 즉, 인수가 동일해야합니다 NSInvocation
에서 얻을)
답을 준수하는 테스트가 NO이지만, 내 이전 시점이었다 그랬던 잘못된 생각 ...
@interface Test : NSObject
@end
@implementation Test
- (void)testMethodWithBlock:(void (^)(void))block obj:(id)obj cstr:(const char *)cstr {
NSLog(@"%p %p %p %@", block, obj, cstr, [block class]);
}
@end
@implementation testTests
- (void)test1 {
__block int dummy;
Test *t = [[Test alloc] init];
NSMethodSignature *ms = [t methodSignatureForSelector:@selector(testMethodWithBlock:obj:cstr:)];
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:ms];
void (^block)(void) =^{
dummy++; // stop this become global block
};
id obj = @"object";
char *cstr = malloc(5);
strcpy(cstr, "cstr");
NSLog(@"%@", [ms debugDescription]);
NSLog(@"%p %p %p %@", block, obj, cstr, [block class]);
[invocation setSelector:@selector(testMethodWithBlock:obj:cstr:)];
[invocation setArgument:&block atIndex:2];
[invocation setArgument:&obj atIndex:3];
[invocation setArgument:&cstr atIndex:4];
[invocation invokeWithTarget:t];
[invocation retainArguments];
[invocation invokeWithTarget:t];
free(cstr);
}
@end
출력, ARC가 비활성화 (추락) :
,
2013-04-18 19:49:27.616 test[94555:c07] 0xbfffe120 0x70d2254 0x7167980 __NSStackBlock__
2013-04-18 19:49:27.617 test[94555:c07] 0xbfffe120 0x70d2254 0x7167980 __NSStackBlock__
2013-04-18 19:49:27.618 test[94555:c07] 0xbfffe120 0x70d2254 0x736a810 __NSStackBlock__
는 ARC가 활성화 :
2013-04-18 19:51:03.979 test[95323:c07] 0x7101e10 0x70d2268 0x7101aa0 __NSMallocBlock__
2013-04-18 19:51:03.979 test[95323:c07] 0x7101e10 0x70d2268 0x7101aa0 __NSMallocBlock__
2013-04-18 19:51:03.980 test[95323:c07] 0x7101e10 0x70d2268 0xe0c1310 __NSMallocBlock__
당신이 볼 수 있듯이, C 문자열이 retainArguments
하지만 블록으로 복사됩니다. 하지만 ARC가 활성화 된 상태에서 ARC가 어느 시점에서 사용자를 대신하여 복사 했으므로 문제가 없어집니다.
업데이트 해 주셔서 감사합니다. – matt