मैं ब्लॉक तर्कों को NSInvocation
पर पास करने का प्रयास कर रहा हूं, लेकिन ऐप क्रैश हो जाता है। आमंत्रण नेटवर्क अनुरोध करता है और सफलता या विफलता ब्लॉक को कॉल करता है। मुझे लगता है कि समस्या यह है कि नेटवर्क अनुरोध समाप्त होने से पहले ब्लॉक को हटा दिया जाता है। मैं इसे Block_copy
हैकररी के साथ काम करने में कामयाब रहा और यह इंस्ट्रूमेंट्स का उपयोग करके किसी भी रिसाव की रिपोर्ट नहीं करता है।ब्लॉक तर्कों के साथ एनएसआईएनवोकेशन
प्रश्न: - क्या यह संभव है कि स्थिर विश्लेषक या उपकरण इसकी रिपोर्ट नहीं कर रहे हैं, तो यह रिसाव है? - क्या ब्लॉक को "बनाए रखने" का कोई बेहतर तरीका है?
// Create the NSInvocation
NSMethodSignature *methodSignature = [target methodSignatureForSelector:selector];
NSInvocation* invoc = [NSInvocation invocationWithMethodSignature:methodSignature];
[invoc setTarget:target];
[invoc setSelector:selector];
// Create success and error blocks.
void (^successBlock)(id successResponse) = ^(id successResponse) {
// Some success code here ...
};
void (^errorBlock)(NSError *error) = ^(NSError *error) {
// Some failure code here ...
};
/*
Without the two Block_copy lines, the block gets dealloced too soon
and the app crashes with EXC_BAD_ACCESS
I tried [successBlock copy] and [failureBlock copy] instead,
but the app still crashes.
It seems like Block_copy is the only way to move the block to the heap in this case.
*/
Block_copy((__bridge void *)successBlock);
Block_copy((__bridge void *)errorBlock);
// Set the success and failure blocks.
[invoc setArgument:&successBlock atIndex:2];
[invoc setArgument:&errorBlock atIndex:3];
[invoc retainArguments]; // does not retain blocks
// Invoke the method.
[invoc invoke];
अपडेट: मैंने कोड को नीचे अपडेट किया है। ब्लॉक NSMallocBlocks
हैं, लेकिन ऐप अभी भी दुर्घटनाग्रस्त है।
// Create success and error blocks.
int i = 0;
void (^successBlock)(id successResponse) = ^(id successResponse) {
NSLog(@"i = %i", i);
// Some success code here ...
};
void (^errorBlock)(NSError *error) = ^(NSError *error) {
NSLog(@"i = %i", i);
// Some failure code here ...
};
/*** Both blocks are NSMallocBlocks here ***/
// Set the success and failure blocks.
void (^successBlockCopy)(id successResponse) = [successBlock copy];
void (^errorBlockCopy)(NSError *error) = [errorBlock copy];
/*** Both blocks are still NSMallocBlocks here - I think copy is a NoOp ***/
// Set the success and failure blocks.
[invoc setArgument:&successBlockCopy atIndex:2];
[invoc setArgument:&errorBlockCopy atIndex:3];
[invoc retainArguments]; // does not retain blocks
// Invoke the method.
[invoc invoke];
ब्लॉक श्रृंखला में नीचे पारित कर रहे हैं इस प्रकार है: → method1
→ methodN
methodN
अंततः HTTP के आधार पर सफलता या विफलता ब्लॉक कॉल
NSInvocation
→ NSProxy
(forwardInvocation:
NSInvocation
का प्रयोग करके) प्रतिक्रिया।
क्या मुझे हर चरण में ब्लॉक की प्रतिलिपि बनाने की आवश्यकता है? ऊपर दिया गया उदाहरण पहले NSInvocation
के बारे में बात कर रहा था। क्या मुझे हर उचित चरण में [invocation retainArguments];
की भी आवश्यकता है? मैं एआरसी का उपयोग कर रहा हूँ।
मैंने सफलता की कोशिश की हैब्लॉक = [सफलताब्लॉक पुलिस y]; और त्रुटिब्लॉक = [त्रुटि ब्लॉक कॉपी]; लेकिन मुझे इस त्रुटि के साथ एक ही दुर्घटना मिलती है: पते में कोई ऐसा अनुभाग नहीं होता है जो किसी ऑब्जेक्ट फ़ाइल में किसी सेक्शन को इंगित करता है। जैसा कि मैंने उल्लेख किया है, उल्लेख के अनुसार ब्लॉक_copy लाइनों को जोड़ना दुर्घटना को रोकता है, लेकिन मुझे यकीन नहीं है कि वे स्मृति को रिसाव करते हैं या नहीं। – pshah
'ब्लॉक_copy' जिसका आप वर्तमान में उपयोग करते हैं उसका कोई दस्तावेज प्रभाव नहीं है। आप जो कुछ भी देख रहे हैं वह यह है कि समस्याग्रस्त 'इनवोक' के कारण अनिर्धारित परिणाम एक अलग अपरिभाषित प्रभाव रखते हैं। यह एक असली समाधान नहीं है। और यहां तक कि लाश भी आपको डीबग करने में मदद नहीं करेंगे, क्योंकि वे ढेर वस्तुओं को कृत्रिम रूप से जीवित नहीं रख सकते हैं - एक बार ढेर बढ़ने के बाद यह उन्हें ओवरराइट कर देगा। – Tommy
मैं इस धारणा के तहत था कि ब्लॉक_copy कॉलिंग ब्लॉक को ढेर के बजाय ढेर पर सहेजने के लिए मजबूर करता है। और, मैं अभी भी यह नहीं समझ सकता कि सफलता के बजाय [सफलताब्लॉक कॉपी] में क्यों गुजर रहा है आमंत्रण के लिए लॉग इन काम नहीं करेगा। – pshah