在OSX上的C ++ / Objective-C应用程序中执行拖动操作时崩溃

时间:2014-09-05 14:36:38

标签: macos cocoa drag-and-drop xcode5 objective-c++

我有一个大型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成员变量指针。它没有改善为dragImage和event提供NULL的行为。粘贴板有一个与列表项相关的文件名列表。

这是一个典型的崩溃报告(其中总是有一个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 个答案:

答案 0 :(得分:0)

这是代码中的内存管理错误。第二个崩溃日志显示一条​​消息-member:被发送到一个没有响应它的对象(一个NSNumber),这强烈暗示该消息的目标应该是所做的类回复-member:。这是一个很大的线索,因为我敢打赌这是你自己的代码。在某个地方,您尝试在已经释放后向对象发送消息。也许你忘了在某个地方保留拖拽的东西?也许你过度释放(如果你没有使用ARC或垃圾收集)?你有一个悬而未决的参考资料吗?说不上。

您应该使用的工具是使用Zombies乐器的乐器。运行应用程序,使其崩溃,然后让Instruments标记您“向僵尸对象发送消息”的点(在这种情况下,仪器实际上不会释放对象,而是保留它们并将它们标记为“僵尸” - 不死对象 - 并监视发送给应该在其保留计数达到零之后解除分配的对象的消息。单击popover消息中的箭头,并密切关注该对象的整个生命周期(就创建它的位置以及发送的所有保留/释放消息以及从何处发送)。这是追踪这种性质的唯一可靠方法:在仪器中的Zombies乐器下运行时使其失败。