Core data, faulting, and NSZombieEnabled = EXC_BAD_ACCESS

146 Views Asked by At

So, I have this problem, my app plays audio, and it stored the playback position whenever paused is triggered, either by tapping a button, or selecting other track. When the latter happen, I programatically call pause: and set 0.5 sec delay before start playing the next track, this is where the problem occurs.

The code is dead simple.

NSInteger x = [_player currentPlaybackTime];
if (x && x > 0) {
    [_nowPlaying setValue:[NSNumber numberWithInt:x] forKey:@"pausedAt"];

    NSError *ctxErr;
    if (![_context save:&ctxErr]) {
        NSLog(@"Save error: %@", [ctxErr localizedDescription]);
    }
}

(_nowPlaying is NSManagedObject if it helps)

And it crashes for the line [_nowPlaying setValue: forKey:]

So, I add NSZombieEnabled to the environment variable and the logs report "Caught CoreData could not fulfill a fault for"

Okay, so I check for [_nowPlaying isFault], I figured since I also call the function every few seconds, it's not critical if it not saving at that particular point. It's working fine with 0 messages from NSZombie.

Here comes the problem, when I unchecked NSZombieEnabled, the app crashes on [_nowPlaying isFault] with EXC_BAD_ACCESS. Which apparently meant that I've got a plain old crash.

Now, I'm completely lost. Any idea where to go from here?

Update: responding to @ArkadiuszHolko comment

Thought it was obvious, but here it is:

[[[SRAudioPlayer sharedAudioPlayer] player] pause];
[self performSelector:@selector(setPlayback) withObject:nil afterDelay:0.5f];

And setPlayback is just

NSManagedObject *episode = [_fetchedResultsController objectAtIndexPath:indexPath];
[[SRAudioPlayer sharedAudioPlayer] setNowPlaying:episode];
2

There are 2 best solutions below

1
Daniel Broad On

Are you using ARC? - who is holding onto _nowPlaying?

The best way in my experience to establish if an object is deleted is

[myManagedContext existingObjectForObjectID: _nowPlaying.objectID]!=nil
0
Arek Holko On

In response to your comment:

And that code still crash with * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFDictionary objectID]: unrecognized selector sent to instance 0x104ab9c0'.

It seems that your _nowPlaying (or some other object) is an NSDictionary, where Core Data expects it to be NSManagedObject.