0

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];
Community
  • 1
  • 1
marko
  • 1,721
  • 15
  • 25
  • (Side note, unrelated to your problem: `if (x && x > 0)` is the same as `if (x > 0)`.) – Martin R Oct 11 '13 at 07:17
  • Can you show the code responsible for `I programatically call pause: and set 0.5 sec delay before start playing the next track, this is where the problem occurs.`? – Arek Holko Oct 11 '13 at 08:33
  • @ArkadiuszHolko updated. And MartinR, yeah I know, but early in dev, I've encountered x is nil for some reason, and it's not impacting performance that much. So I just left it there. – marko Oct 11 '13 at 08:58
  • @soemarko: Where does the `indexPath` variable come from in `setPlayback`? Can you check if `episode` isn't set to `nil`? – Arek Holko Oct 11 '13 at 09:05
  • @ArkadiuszHolko it's never nil. The audio stream online, and the list episode never get deleted from the app. Anyway, just tried and add `if (_nowPlaying == nil) return;`. Didn't helped, and I saw in the debugger, it wasn't nil. – marko Oct 11 '13 at 09:22
  • @soemarko: Can you post a full source of this view controller? – Arek Holko Oct 11 '13 at 09:25
  • @ArkadiuszHolko I could, you'll probably don't get the half of it anyway (it depends on a lot of other stuff). The problem is that I can't create a simple test app for this case with significant effort of creating the same app 80% of the way. However, you seemed convinced that the problem was with the view controller not the player singleton. I'll pursue the problem in that direction. Thanks! – marko Oct 11 '13 at 09:33
  • I wanted you to post the full source, because some things aren't clear: when and how do you set `_nowPlaying`? Is it created and updated in the same thread? How does it relate to `episode`? – Arek Holko Oct 11 '13 at 09:40
  • Yes it's created in the same thread. _nowPlaying and episode is the same reference. However, I've fix it. your idea of checking _nowPlaying, gave me an idea for setting _nowPlaying to nil before pausing and change track. In effect, it's the same with the original checking isFault solution. – marko Oct 11 '13 at 09:48

2 Answers2

0

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
Daniel Broad
  • 2,512
  • 18
  • 14
  • Yes to ARC. The singleton is holding _nowPlaying. 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 while _nowPlaying is not nil, I can't read anything from it. Forcing it to be nil, and missed the save point by a few seconds still the best solution. But I'll leave this question open and create a snapshot while keep working on other stuff. – marko Oct 11 '13 at 11:21
0

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.

Arek Holko
  • 8,966
  • 4
  • 28
  • 46