如何在Xcode堆栈跟踪

时间:2015-07-18 19:17:28

标签: ios objective-c xcode debugging stack-trace

我正在使用Objective-C中的iPhone应用程序(使用Xcode 6.1.1和Parse),我刚刚得到了这个神秘的NSInternalInconsistencyException

Caught "NSInternalInconsistencyException" with reason "Tried to save an object with a pointer to a new, unsaved object.":

所以我对Stack Overflow社区的问题是:

有人如何读取此堆栈跟踪以查找问题的实际来源?我没有在此堆栈跟踪中的任何位置看到任何可识别的文件名,方法调用或行号。

或者,如果不是简单地读取堆栈跟踪并且涉及其他技术,那么开发人员应该采取哪些适当的下一步来追踪此类错误的来源?

以下是输出到我的控制台的完整堆栈跟踪:

2015-07-18 02:01:17.596 testapp[1276:60b] [Error]: Caught "NSInternalInconsistencyException" with reason "Tried to save an object with a pointer to a new, unsaved object.":
(
    0   CoreFoundation                      0x2f547f9b  + 154
    1   libobjc.A.dylib                     0x39c94ccf objc_exception_throw + 38
    2   CoreFoundation                      0x2f547ec5  + 0
    3   testapp                             0x00205a29 -[PFObject(Private) resolveLocalId] + 384
    4   testapp                             0x00233d6d __32-[PFRESTCommand resolveLocalIds]_block_invoke + 24
    5   testapp                             0x00233783 +[PFRESTCommand forEachLocalIdIn:doBlock:] + 642
    6   testapp                             0x00233ba7 __42+[PFRESTCommand forEachLocalIdIn:doBlock:]_block_invoke + 62
    7   CoreFoundation                      0x2f484043  + 98
    8   CoreFoundation                      0x2f483f67  + 162
    9   testapp                             0x0023367f +[PFRESTCommand forEachLocalIdIn:doBlock:] + 382
    10  testapp                             0x00233ba7 __42+[PFRESTCommand forEachLocalIdIn:doBlock:]_block_invoke + 62
    11  CoreFoundation                      0x2f484043  + 98
    12  CoreFoundation                      0x2f483f67  + 162
    13  testapp                             0x0023367f +[PFRESTCommand forEachLocalIdIn:doBlock:] + 382
    14  testapp                             0x0023373f +[PFRESTCommand forEachLocalIdIn:doBlock:] + 574
    15  testapp                             0x00233ba7 __42+[PFRESTCommand forEachLocalIdIn:doBlock:]_block_invoke + 62
    16  CoreFoundation                      0x2f484043  + 98
    17  CoreFoundation                      0x2f483f67  + 162
    18  testapp                             0x0023367f +[PFRESTCommand forEachLocalIdIn:doBlock:] + 382
    19  testapp                             0x00233ca3 -[PFRESTCommand forEachLocalId:] + 162
    20  testapp                             0x00233d3f -[PFRESTCommand resolveLocalIds] + 34
    21  testapp                             0x0023ee2f -[PFRESTCommandRunner _runCommandAsync:withCancellationToken:] + 110
    22  testapp                             0x0023e8c7 -[PFRESTCommandRunner runCommandAsync:withOptions:cancellationToken:] + 174
    23  testapp                             0x0023e7d7 -[PFRESTCommandRunner runCommandInBackground:inOperation:] + 42
    24  testapp                             0x00203667 __65+[PFObject(Private) _deepSaveAsync:withCurrentUser:sessionToken:]_block_invoke_3 + 766
    25  testapp                             0x002854b3 __55-[BFTask continueWithExecutor:block:cancellationToken:]_block_invoke_2 + 214
    26  libdispatch.dylib                   0x3a17c833  + 10
    27  libdispatch.dylib                   0x3a183ad7  + 222
    28  libdispatch.dylib                   0x3a183d29  + 56
    29  libsystem_pthread.dylib             0x3a2bebd3 _pthread_wqthread + 298
    30  libsystem_pthread.dylib             0x3a2bea98 start_wqthread + 8
).

感谢您提供给我的任何帮助和见解。

3 个答案:

答案 0 :(得分:4)

这个特殊的例子并没有让开发人员继续下去。因此,在这种情况下,您的问题的答案是“Google it”。实际上,堆栈跟踪的最佳线索是:

[PFObject(Private) _deepSaveAsync:withCurrentUser:sessionToken:]

上面的行表示使用currentUser的失败保存,并结合错误消息“尝试使用指向新未保存对象的指针保存对象”。应足以指出可能的原因。

事实证明,这个错误并不罕见,并且令人困惑的是为什么Parse没有解决它。这通常是由于您的应用程序使用匿名Parse用户并且在保存用户对象之前尝试保存对象。由于尚未保存用户对象,因此它没有objectId,另一个对象的保存失败。

解决方案是检查currentUser对象是否有objectId,如果没有,请先尝试保存,然后再尝试写入Parse。

    // Prevent race condition for unsaved user
    // Courtesy of: http://samwize.com/2014/07/15/pitfall-with-using-anonymous-user-in-parse/
    if ([PFUser currentUser].objectId == nil) {
        [[PFUser currentUser] saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
            //do stuff later
        }];
    } else {
        //do stuff now
    }

答案 1 :(得分:2)

当代码进入一个永远不会发生的状态时,抛出

NAME User1 User1Altname1 User1Altname2 User2 。通常它表示编写它的人所犯的错误,但有时可能会因错误使用库而导致这种情况(例如,根据文档的说法做一些事情)。

换句话说,这是一个错误,但如果你没有编写抛出它的代码,它可能不是你的。从这个特定的堆栈跟踪,问题必须在Parse。

将错误报告给原始开发人员。无论你是否滥用它,一个好的图书馆绝不能扔掉它。在他们修复它之前,你可以做的最好的事情就是尝试通过以某种不同的方式做你想做的事来解决它。如果您拥有该库的源代码,则可以尝试自行调试并解决问题。

答案 2 :(得分:1)

当您看到此类错误并且Xcode将您踢到AppDelegate时,请尝试放入Xcode 2种断点

  • 快速错误断点
  • 异常断点...

您将在顶部左侧面板中找到这些选项

Breakpoint Navigator-> +(您将在底部找到此simbol)-> Swift错误断点或/和异常断点

希望这对您下次有帮助

  1. enter image description here

  2. enter image description here