मैं मैदान में अपने कई उपयोगकर्ताओं द्वारा रिपोर्ट की गई एक क्रैशिंग बग डीबग करने का प्रयास कर रहा हूं। सभी मुझे एक ही ढेर दिखाने:आईओएस 9 .1 में dispatch_async पर एक SIGABRT को ट्रिगर कर सकता है?
Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
Triggered by Thread: 8
OS Version: iOS 9.1 (13B143)
Code Type: ARM (Native)
0 libsystem_kernel.dylib 0x392ccc84 0x392b8000 + 85124
1 libsystem_pthread.dylib 0x39370732 0x3936c000 + 18226
2 libsystem_c.dylib 0x39264f9a 0x3921a000 + 307098
3 libsystem_c.dylib 0x39264f2c 0x3921a000 + 306988
4 libsystem_c.dylib 0x392447ea 0x3921a000 + 174058
5 MyApp 0x000cb3e0 __69-[MyDataManager myMethod:]_block_invoke (MyDataManager.m:2367)
लाइन 2367 बस है:
2363: BOOL success = [db executeUpdate:@"INSERT INTO table (id, content) VALUES (?, ?)", message.remoteId, message.content];
2364: assert(success);
2365: DebugLog(@"DB Results %d", success);
2366:
2367: dispatch_async(dispatch_get_main_queue(), ^{
2368: [self cleanupMethod:args];
2369: });
जबकि वहाँ निश्चित रूप से है कि ब्लॉक के भीतर कोड है, यह केवल 1 लाइन लंबी है, और है कि कोड निष्पादित करने के लिए प्रकट नहीं होता है इस ढेर पर अन्यथा मैं cleanupMethod
myMethod
से ऊपर देखता हूं।
संपादित करें: आप इसे देख सकते हैं, dispatch_async से ठीक पहले, एक जोर है! मैंने मूल रूप से सोचा था कि यह दुर्घटना जोरदार थी। लेकिन रेखा संख्याओं का मिलान कभी नहीं हुआ - जोर से कई लाइनें ऊपर थीं (लाइन 2364, 2367 नहीं) - और जब मैंने इसे और परीक्षण किया, तो मैंने देखा कि अगर जोर ट्रिगर होता है, तो मेरे ढेर में _block_invoke
शामिल नहीं होगा myMethod को कॉल के अंत में जोड़ा जा सकता है।
क्या कोई सुझाव दे सकता है कि dispatch_async इस व्यवहार को कैसे ट्रिगर कर सकता है? इसके अलावा, क्या libsystem_c.dylib में ऐप्पल के कोड का प्रतीक होने का कोई तरीका है? libsystem_c.dylib की
बाइनरी छवि:
0x3921a000 - 0x3927efff libsystem_c.dylib armv7 <0b5d65608e6f38448cd207fbd748d372> /usr/lib/system/libsystem_c.dylib
नोट: प्रश्न में वस्तु यदि आप एक वैश्विक सिंगलटन, मेरी "डेटा प्रबंधक" है। यह नेटवर्क अनुरोधों को संभालता है और राज्य को संग्रहीत करता है जिसे UIViewControllers के बीच साझा करने की आवश्यकता हो सकती है। यह मूल रूप से इस प्रकार के रूप में घोषित किया गया है:
+ (MyDataManager *)mainStore {
static dispatch_once_t once;
static id sharedInstance;
dispatch_once(&once, ^{
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}
मैं वस्तु के परिणामों को समझने जब मेरे cleanupMethod:args
विधि कहा जाता है पुनः आवंटित की जाती किया जा रहा ... लेकिन मैं सोचा मेरी वैश्विक सिंगलटन हमेशा के आसपास है और इस तरह हमेशा के लिए सुरक्षित हो जाएगा था मेरे कोड में जिस तरह से मैं कॉल करता हूं? मैं फिर से चक्रों को बरकरार रखने के बारे में चिंतित नहीं हूं, यह एक वैश्विक सिंगलटन माना जाता है।
क्या यह कोड नमूना ठीक है?
@interface MyDataManager
@end
@implementation MyDataManager
+ (MyDataManager *)mainStore {
static dispatch_once_t once;
static id sharedInstance;
dispatch_once(&once, ^{
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}
- (void)myMethod {
NSDictionary *args = @{...}
...
dispatch_async(dispatch_get_main_queue(), ^{
[self cleanupMethod:args];
});
}
- (void)cleanupMethod:(id)args {
...
}
@end
@interface MyViewController : UIViewController
@end
@implementation MyViewController
- (void)viewDidLoad {
[super viewDidLoad];
[[MyDataManager sharedInstance] myMethod];
}
@end
यदि आप ब्लॉक के सामग्रियों को शामिल करने के लिए अपना प्रश्न संपादित करते हैं, या कम से कम कुछ पंक्तियां MyDataManager.m के लाइन 2367 के बाद संपादित करती हैं। –
@rob mayoff हो गया! – esilver
लगता है कि आपके 'स्वयं' को हटा दिया गया है जब ब्लॉक ब्लॉक –