सं
छवि अगर जवाब है हां, जहां NSInvocation
बहुत चालाक ब्लॉक कॉपी करने के लिए है, यह कुछ इस तरह करना चाहिए:
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
)
अद्यतन
अभी किया जवाब अनुरूप परीक्षण नहीं है, लेकिन मेरे पिछले बात यह थी हालांकि गलत ...
@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
उत्पादन, एआरसी अक्षम (और दुर्घटनाग्रस्त हो गया):
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__
एआरसी सक्षम:
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__
के रूप में आप देख सकते हैं, ग स्ट्रिंग retainArguments
नहीं बल्कि ब्लॉक से कॉपी कर रहे हैं। लेकिन एआरसी सक्षम होने के साथ, समस्या दूर होनी चाहिए क्योंकि एआरसी ने इसे किसी बिंदु पर आपके लिए कॉपी किया है।
इस अद्यतन को रखने के लिए धन्यवाद! – matt