हमारे पास हमारे ऐप में CMMotionManager का एक उदाहरण है जिसका उपयोग हम 5 हर्ट्ज की आवृत्ति पर सेंसर अपडेट प्राप्त करने के लिए करते हैं। निम्नलिखित कोड है जो हम गति अद्यतन शुरू करने के लिए उपयोग करते हैं:रोकथाम पर कोरमोशन क्रैश (आईपैड-केवल) StopDeviceMotionUpdates
[self.motionManager
startDeviceMotionUpdatesUsingReferenceFrame:
CMAttitudeReferenceFrameXMagneticNorthZVertical
toQueue:operationQueue
withHandler:^(CMDeviceMotion *motion, NSError *error) {
if (!error) {
[self doSomethingWithMotion:motion];
} else { ... }
उपर्युक्त विधि हमेशा मुख्य धागे पर आती है।
अब, एक बार हम अपने कार्य के साथ किया जाता है, हम प्रस्ताव अद्यतन निम्न विधि को फोन करके, फिर मुख्य थ्रेड पर रोक:
- (void)stopMotionUpdates {
// This might get called on concurrent threads.
// So better using sync block + make it idempotent
@synchronized(self) {
if (_motionManager.deviceMotionActive) {
[_motionManager stopDeviceMotionUpdates];
_prevPoint = nil;
}
}
}
मुद्दा हम सामना कर रहे हैं यह है कि stopMotionUpdates क्रैश, वह भी केवल आईपैड में। हमने आईफोन और आईपैड पर विभिन्न ओएस संस्करणों के साथ बड़े पैमाने पर इसका परीक्षण किया है और हमें केवल आईओएस 7 और आईओएस 8 दोनों के लिए आईपैड (मिनी 1,2 और रेटिना/गैर-रेटिना) पर क्रैश मिलता है। साथ ही, हम परीक्षण के लिए उपयोग किए जाने वाले सभी आईपैड पर क्रैश को पुन: पेश नहीं कर सकते हैं, लेकिन केवल कुछ ही। अनुसरण कर रहे हैं मुख्य और दुर्घटनाग्रस्त हो गया थ्रेड के लिए दुर्घटना लॉग:
Thread : com.apple.main-thread
0 libsystem_kernel.dylib 0x00000001935f1cdc semaphore_wait_trap + 8
1 libdispatch.dylib 0x00000001934fbb3c _dispatch_semaphore_wait_slow + 252
2 CoreMotion 0x0000000186bf67d4 (null)
3 CoreMotion 0x0000000186be3698 (null)
4 MyApp 0x00000001002f7434 -[MyAppMotionManager stopMotionUpdates]
...
...
12 MyApp 0x00000001002e94f8 __getDispatchTimer_block_invoke
13 libdispatch.dylib 0x00000001934f3fd4 _dispatch_client_callout + 16
14 libdispatch.dylib 0x00000001934f5b90 _dispatch_source_invoke + 500
15 libdispatch.dylib 0x00000001934f7180 _dispatch_main_queue_callback_4CF + 244
16 CoreFoundation 0x00000001864fec2c __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12
17 CoreFoundation 0x00000001864fcf6c __CFRunLoopRun + 1452
18 CoreFoundation 0x000000018643dc20 CFRunLoopRunSpecific + 452
19 GraphicsServices 0x000000018c0ddc0c GSEventRunModal + 168
20 UIKit 0x000000018956efdc UIApplicationMain + 1156
21 MyApp 0x00000001000c9850 main (main.m:14)
22 libdyld.dylib 0x000000019350faa0 start + 4
EXC_BREAKPOINT UNKNOWN at 0x0000000186c257ac
Thread : Crashed: Thread
0 CoreMotion 0x0000000186c257ac (null) + 110504
1 CoreMotion 0x0000000186c25774 (null) + 110448
2 CoreMotion 0x0000000186bf3c84 (null)
3 CoreMotion 0x0000000186bf67ec (null)
4 CoreMotion 0x0000000186bf3b80 (null)
5 CoreMotion 0x0000000186c24c48 (null) + 107588
6 CoreMotion 0x0000000186bf67ec (null)
7 CoreMotion 0x0000000186c24ba4 (null) + 107424
8 CoreMotion 0x0000000186be3b9c (null)
9 CoreMotion 0x0000000186bf6860 (null)
10 CoreFoundation 0x00000001864ff680 __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 20
11 CoreFoundation 0x00000001864fe838 __CFRunLoopDoBlocks + 300
12 CoreFoundation 0x00000001864fd0a4 __CFRunLoopRun + 1764
13 CoreFoundation 0x000000018643dc20 CFRunLoopRunSpecific + 452
14 CoreFoundation 0x00000001864932a8 CFRunLoopRun + 112
15 CoreMotion 0x0000000186bf653c (null)
16 libsystem_pthread.dylib 0x000000019368be1c _pthread_body + 168
17 libsystem_pthread.dylib 0x000000019368bd74 _pthread_body
हम प्रस्ताव अद्यतन हैंडलर ब्लॉक में आत्म संदर्भ के बाद से, वस्तु पूरे कतार तक पुनः आवंटित की जाती नहीं किया जाना चाहिए प्लावित है। किसी भी मदद की सराहना की है :)
stopMotionUpdates विधि एक ViewController में नहीं है, मैं एक अलग MotionManager कि हैंडलिंग की देखभाल और प्रतिनिधियों के लिए गति डेटा पहुंचाने लगता है। जब भी गति डेटा आवश्यकता समाप्त होती है तो हम stopMotionUpdates को कॉल करते हैं। @synchronized इस मामले में कोई म्यूटेक्स लॉक नहीं बना रहा है। –
मुझे आपके साथ असहमत होना है क्योंकि जब आप दुर्घटना का सामना करते हैं तो आपका मुख्य धागा लॉक होता है (semaphore_wait_trap)। – pteofil
यह समस्या है, मैं अपने कोड में कहीं भी मुख्य धागे को लॉक नहीं कर रहा हूं। तो, ऐसा लगता है कि यह CoreMotion के अंदर कहीं से बंद हो रहा है। और दुर्घटना वॉचडॉग टाइमआउट नहीं है। क्या आपको यकीन है कि इस प्रकार का दुर्घटना भी डेडलॉक के कारण होता है? –