EXC_BAD_ACCESS with NSAutoReleasePool, NSThread and NSThreadWillExitNotification
EXC_BAD_ACCESS with NSAutoReleasePool, NSThread and NSThreadWillExitNotification
- Subject: EXC_BAD_ACCESS with NSAutoReleasePool, NSThread and NSThreadWillExitNotification
- From: John Zorko <email@hidden>
- Date: Tue, 14 Oct 2008 07:38:27 -0700
Hello, all ...
I'm experiencing a crash after a thread exits.
Program received signal: “EXC_BAD_ACCESS”.
(gdb) bt
#0 0x300c8c18 in objc_msgSend ()
#1 0x3067073a in NSPopAutoreleasePool ()
#2 0x306770ea in __NSFinalizeThreadData ()
#3 0x31446f6e in _pthread_tsd_cleanup ()
#4 0x31449ae4 in _pthread_exit ()
#5 0x3144b7e8 in pthread_exit ()
#6 0x30676e66 in +[NSThread exit] ()
#7 0x30673444 in __NSThread__main__ ()
#8 0x3144a824 in _pthread_body ()
#9 0x00000000 in ?? ()
(gdb)
The NSThread itself runs well enough. It allocates an autorelease
pool and releases it at the end, like i've seen many NSThreads do:
- (void)startInternal
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
.
.
.
NSLog(@"- startInternal ending ... releasing pool");
[pool release];
exit;
}
I start this thread thusly:
- (void)start
{
streamerThread = [[NSThread alloc] initWithTarget:self
selector:@selector(startInternal) object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(threadStopped)
name:NSThreadWillExitNotification
object:streamerThread];
[streamerThread start];
appDelegate.playbackThreadFinished = false;
}
... and the threadStopped method does this:
- (void)threadStopped
{
NSLog(@"*** streamer thread has stopped ***");
[[NSNotificationCenter defaultCenter] removeObserver:self];
appDelegate.playbackThreadFinished = true;
}
Now, in my main thread, I have an observer on playbackThreadFinished
that I set up as soon as the app launches (before the other thread is
created):
[self addObserver:self forKeyPath:@"playbackThreadFinished" options:0
context:nil];
... and when I see the "playbackThreadFinished" notification, I do
things like see if there is a new song to play, etc.
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
change:(NSDictionary *)change context:(void *)context
{
NSLog(@"observeValueForKeyPath -- current thread ID: %x, keypath:
%s", [NSThread currentThread], [keyPath UTF8String]);
if ([keyPath isEqualToString:@"isPlaying"])
{
.
.
.
return;
}
else if ([keyPath isEqualToString:@"playbackThreadFinished"])
{
if (playbackThreadFinished)
{
// ... if we're in shuffle mode
if (playShuffleFlag)
{
if ([self.shufflePlayedList count] < [self countOfSongList])
{
NSUInteger randomSong;
do
{
randomSong = (int)(rand() % [self countOfSongList]);
}
while ([self.shufflePlayedList indexOfObject:[NSNumber
numberWithInt:randomSong]] != NSNotFound);
NSLog(@"play shuffle advancing to song %i", randomSong);
NSNumber *num = [[NSNumber alloc] initWithInt:randomSong];
[self.shufflePlayedList addObject:num];
[num release];
self.nextSong = randomSong;
}
else
{
NSLog(@"shuffle play has played all songs in the list");
[artistViewController
popToViewController:artistViewController.artistAlbumSongController
animated:YES];
}
}
// ... if we're in album play mode
else if (playEntireAlbumFlag)
{
if (self.currentSong < [self countOfSongList] - 1)
{
self.currentSong ++;
NSLog(@"play album advancing to song %d of %d", self.currentSong,
[self countOfSongList]);
self.nextSong = currentSong;
}
}
// ... if the user just picked a song from the list
else if (self.currentSong > -1)
{
self.nextSong = self.currentSong;
self.currentSong = -1; // reset so the same song won't play again
when it's finished :-)
}
}
return;
}
else if ([keyPath isEqualToString:@"nextSong"])
{
.
.
.
return;
}
[super observeValueForKeyPath:keyPath ofObject:object change:change
context:context];
}
... the crash happens after observeValueForKeyPath finishes. What
confuses me is that the only NSAutoreleasePool allocated is the one
the thread itself allocated, and I didn't autorelease anything in
observeValueForKeyPath. Yes i'm a Cocoa n00b ...
Regards,
John
Falling You - exploring the beauty of voice and sound
http://www.fallingyou.com
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden