我有一个大型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
我没有想法。任何帮助将不胜感激,谢谢。
答案 0 :(得分:0)
这是代码中的内存管理错误。第二个崩溃日志显示一条消息-member:
被发送到一个没有响应它的对象(一个NSNumber),这强烈暗示该消息的目标应该是所做的类回复-member:
。这是一个很大的线索,因为我敢打赌这是你自己的代码。在某个地方,您尝试在已经释放后向对象发送消息。也许你忘了在某个地方保留拖拽的东西?也许你过度释放(如果你没有使用ARC或垃圾收集)?你有一个悬而未决的参考资料吗?说不上。
您应该使用的工具是使用Zombies乐器的乐器。运行应用程序,使其崩溃,然后让Instruments标记您“向僵尸对象发送消息”的点(在这种情况下,仪器实际上不会释放对象,而是保留它们并将它们标记为“僵尸” - 不死对象 - 并监视发送给应该在其保留计数达到零之后解除分配的对象的消息。单击popover消息中的箭头,并密切关注该对象的整个生命周期(就创建它的位置以及发送的所有保留/释放消息以及从何处发送)。这是追踪这种性质的唯一可靠方法:在仪器中的Zombies乐器下运行时使其失败。