Сбой во время операций перетаскивания в приложении C++/Objective-C в OSX
У меня есть большое приложение на C++ с некоторыми смешанными Objective-C, созданным с помощью XCode 5. В одном представлении приложения есть список элементов. Перетаскивание элементов списка будет нормально работать в течение 5, 10 или 50 раз, но в конечном итоге приложение будет зависать при перетаскивании. Он никогда не падает при запуске из XCode (сборка выпуска или отладки). Он не падает, когда я запускаю сборку отладки извне. Вылетает только при запуске сборки релиза извне.
Вот фрагмент кода, который начинает операцию перетаскивания (сбой происходит перед возвратом из dragImage):
// start drag
m_bDragging = true;
[[pHost getView]
dragImage:pDragImage
at:ptOffset.getNSPoint()
offset:NSZeroSize
event:pEvent
pasteboard:[NSPasteboard pasteboardWithName:NSDragPboard]
source:[pHost getView]
slideBack:YES];
m_bDragging = false;
[pHost getView] возвращает указатель на переменную-член NSView. Это не улучшает поведение, чтобы обеспечить NULL для dragImage и события. У монтажной панели есть список имен файлов, связанных с элементами списка.
Вот типичный отчет о сбое (в котором всегда есть CFSetGetValue):
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x0000025900000100
VM Regions Near 0x25900000100:
CG shared images 00000001c871f000-00000001c8727000 [ 32K] r--/r-- SM=SHM
-->
JS JIT generated code 00002ece70800000-00002ece70801000 [ 4K] ---/rwx SM=NUL
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 com.apple.CoreFoundation 0x00007fff9a8c06a9 CFSetGetValue + 25
1 com.apple.CoreFoundation 0x00007fff9a8d81df __CFRunLoopFindMode + 223
2 com.apple.CoreFoundation 0x00007fff9a902a39 CFRunLoopAddTimer + 153
3 com.apple.HIServices 0x00007fff9265bf15 StartIPCPing + 166
4 com.apple.HIToolbox 0x00007fff986956bf __DragInfoPtrSetValueForKey + 160
5 com.apple.HIToolbox 0x00007fff98695616 __CoreDragSetValueForKey + 52
6 com.apple.AppKit 0x00007fff905c968d __50-[NSDragDestination _resetUpdateDraggingItemTimer]_block_invoke + 164
7 libdispatch.dylib 0x00007fff96beb1bb _dispatch_call_block_and_release + 12
8 libdispatch.dylib 0x00007fff96be828d _dispatch_client_callout + 8
9 libdispatch.dylib 0x00007fff96bf0433 _dispatch_after_timer_callback + 77
10 libdispatch.dylib 0x00007fff96be828d _dispatch_client_callout + 8
11 libdispatch.dylib 0x00007fff96bea885 _dispatch_source_invoke + 413
12 libdispatch.dylib 0x00007fff96befe97 _dispatch_main_queue_callback_4CF + 244
13 com.apple.CoreFoundation 0x00007fff9a9404f9 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9
14 com.apple.CoreFoundation 0x00007fff9a8fb714 __CFRunLoopRun + 1636
15 com.apple.CoreFoundation 0x00007fff9a8fae75 CFRunLoopRunSpecific + 309
16 com.apple.HIToolbox 0x00007fff98634a0d RunCurrentEventLoopInMode + 226
17 com.apple.HIToolbox 0x00007fff986347b7 ReceiveNextEventCommon + 479
18 com.apple.HIToolbox 0x00007fff986345bc _BlockUntilNextEventMatchingListInModeWithFilter + 65
19 com.apple.AppKit 0x00007fff902bb24e _DPSNextEvent + 1434
20 com.apple.AppKit 0x00007fff902ba89b -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 122
21 com.apple.AppKit 0x00007fff905c9170 NSCoreDragBlockingProc + 107
22 com.apple.HIServices 0x00007fff9265a230 SampleMouseAndKeyboard + 102
23 com.apple.HIServices 0x00007fff92659f50 DragInApplication + 50
24 com.apple.HIServices 0x00007fff92659177 CoreDragStartDragging + 519
25 com.apple.AppKit 0x00007fff905c5a54 -[NSCoreDragManager _dragUntilMouseUp:accepted:] + 862
26 com.apple.AppKit 0x00007fff9077d3a4 -[NSCoreDragManager dragImage:fromWindow:at:offset:event:pasteboard:source:slideBack:] + 1355
27 com.apple.AppKit 0x00007fff90a6385b -[NSWindow(NSDrag) d
Другой аварийный журнал начался как это:
2014-09-04 19:47:59.659 myApp[47690:507] -[__NSCFNumber member:]: unrecognized selector sent to instance 0x5907
2014-09-04 19:47:59.687 myApp[47690:507] An uncaught exception was raised
2014-09-04 19:47:59.688 myApp[47690:507] -[__NSCFNumber member:]: unrecognized selector sent to instance 0x5907
2014-09-04 19:47:59.688 myApp[47690:507] (
0 CoreFoundation 0x00007fff9a9d925c __exceptionPreprocess + 172
1 libobjc.A.dylib 0x00007fff92958e75 objc_exception_throw + 43
2 CoreFoundation 0x00007fff9a9dc12d -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
3 CoreFoundation 0x00007fff9a937272 ___forwarding___ + 1010
4 CoreFoundation 0x00007fff9a936df8 _CF_forwarding_prep_0 + 120
5 CoreFoundation 0x00007fff9a8c0721 CFSetGetValue + 145
У меня нет идей. Любая помощь будет оценена, спасибо.
1 ответ
Это ошибка управления памятью в вашем коде. Второй аварийный журнал показывает сообщение -member:
был отправлен объекту, который не отвечает на него (NSNumber), что настоятельно предполагает, что целью сообщения должен был быть класс, который отвечает на -member:
, Это большая подсказка, потому что, держу пари, это ваш собственный код. В какой-то момент вы пытаетесь отправить сообщение объекту после его освобождения. Может быть, вы забыли оставить где-нибудь затянутую вещь? Может быть, вы переиздали (если вы не используете ARC или сборщик мусора)? У вас есть свисающая ссылка, которую вы не обнулили? Не знаю.
Инструмент, который вы должны использовать, это Инструменты, с инструментом Зомби. Запустите приложение, сделайте его аварийное завершение, затем позвольте инструментам пометить точку, в которой вы "отправили сообщение объекту-зомби" (в этом случае инструмент фактически не освобождает объекты, а скорее сохраняет их вокруг и помечает их как "зомби"). - объекты нежити - и следит за сообщениями, отправленными объектам, которые должны были быть освобождены после того, как их количество сохраненных достигло нуля). Нажмите на стрелку в всплывающем сообщении и обратите самое пристальное внимание на весь срок службы этого объекта (с точки зрения того, где он был создан, а также всех сохраненных / выпущенных сообщений, отправленных и откуда). Это единственный надежный способ отследить ошибку такого рода: заставить ее выйти из строя во время работы под инструментом "Зомби" в инструментах.