• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
EXC_BAD_ACCESS with NSAutoReleasePool, NSThread and NSThreadWillExitNotification
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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


  • Follow-Ups:
    • Re: EXC_BAD_ACCESS with NSAutoReleasePool, NSThread and NSThreadWillExitNotification
      • From: Ken Thomases <email@hidden>
    • Re: EXC_BAD_ACCESS with NSAutoReleasePool, NSThread and NSThreadWillExitNotification
      • From: "Jonathan del Strother" <email@hidden>
  • Prev by Date: Re: UI elements in custom view mess up drawing
  • Next by Date: Re: EXC_BAD_ACCESS with NSAutoReleasePool, NSThread and NSThreadWillExitNotification
  • Previous by thread: Re: UI elements in custom view mess up drawing
  • Next by thread: Re: EXC_BAD_ACCESS with NSAutoReleasePool, NSThread and NSThreadWillExitNotification
  • Index(es):
    • Date
    • Thread