Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Find the Source of an NSInternalInconsistencyException in an Xcode Stack Trace

I am working on an iPhone app in Objective-C (using Xcode 6.1.1, and Parse), and I just got this mysterious NSInternalInconsistencyException:

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

So my question to the Stack Overflow community is:

How does someone read this stack trace to hunt down the actual source of the problem? I don't see any recognizable filenames, method calls or line numbers anywhere in this stack trace.

Or, if it's not a matter of simply reading the stack trace, and other techniques are involved, then what is the appropriate next step a developer should take to track down the source of this type of error?

Here is the full stack trace that outputs to my console:

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
).

I appreciate any help and insights you can offer me.

like image 685
Ichigo Kurosaki Avatar asked Jul 18 '15 19:07

Ichigo Kurosaki


3 Answers

This particular example doesn't give the developer much to go on. So, the answer to your question in this case is "Google it." Really, the best clue from the stack trace is the line:

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

The line above indicates a failed save using currentUser, combined with the error message "Tried to save an object with a pointer to a new, unsaved object." should be enough to point to a probable cause.

As it turns out, this error is not uncommon and is bewildering why Parse does not fix it. It is generally caused by when your app is using anonymous Parse users and it attempts to save an object prior to the user object having been saved. Since the user object has not been saved, it has no objectId and the save of the other object fails.

The solution is to check to see if the currentUser object has an objectId, and if not, save it first before trying to write to 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
    }
like image 70
picciano Avatar answered Sep 20 '22 01:09

picciano


NSInternalInconsistencyException is thrown when a code enters a state which is never supposed to happen. Usually it indicates a bug made by those who wrote it, though sometimes it is possible to cause such condition by mis-using the library (doing something against what the docs say, for instance).

In other words, it's a bug, but if you didn't write the code that throws it, it's probably not yours. From this particular stack trace, the problem has to be in Parse.

Report the bug to the original developers. A good library must never throw that, regardless if you are misusing it or not. Until they fix it, the best you can do is try to workaround it, by doing what you were trying to do in some different way. If you have the sources of that library, you could try to debug and fix the problem yourself.

like image 26
hamstergene Avatar answered Sep 20 '22 01:09

hamstergene


When you see such kind of errors and Xcode kicks you to AppDelegate, try to put in Xcode 2 kind of breakpoints

  • Swift Error Breakpoint
  • Exception Breakpoint ...

You will find these options in the left panel on the top

Breakpoint Navigator -> + (this simbol you'll find at the bottom side) -> Swift Error Breakpoint or/and Exception Breakpoint

Hope this will help you next time

  1. enter image description here

  2. enter image description here

like image 33
korgx9 Avatar answered Sep 18 '22 01:09

korgx9