sayılı
Görüntü, böyle bir şey yapmak gerekir:
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];
}
}
}
sorun kopyalanırken arg
değiştirilmiş olmasıdır Bu, retainArguments
numaralı aramanın NSInvocation
'daki argümanları değiştirebileceği anlamına gelmeyecek olan blok. , bu zaten yapılmış olan birçok varsayımı bozacaktır.
Güncelleme (argümanlar NSInvocation
oluşturmak için kullanıldığı gibi yani argümanlar aynı olmalıdır NSInvocation
aldığım)
cevap uymak testi HAYIR, ama benim önceki noktasıydı tıpkı yanlış olsa ...
@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
çıkışı, ARC devre dışı (ve çöktü):
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 etkin:
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__
gördüğünüz gibi, c dize retainArguments
ancak blokların tarafından kopyalanır. ama ARC etkinken, sorun bir noktada ARC'nin sizin için kopyaladığı için sorun gitmelidir.
Bu güncelleştirmeyi sakladığınız için teşekkür ederiz! – matt