MPMusicPlayerController function stop causes crash
I use codes below to play ipod audio library.
if( musicPlayer==nil)
{
MPMusicPlayerController* playa=[[MPMusicPlayerController alloc]init];
musicPlayer=playa;
[ playa release];
}
musicPlayer = [MPMusicPlayerController applicationMusicPlayer];
[musicPlayer setShuffleMode: MPMusicShuffleModeOff];
[musicPlayer setRepeatMode: MPMusicRepeatModeNone];
[musicPlayer setQueueWithItemCollection: userMediaItemCollection];
[musicPlayer play];
when I pressed a button, it will fire function below to stop playing
-(void)stopMusicPlayer;
{
if (playbackState == MPMusicPlaybackStatePlaying) {
[ musicPlayer开发者_Python百科 stop];
}
}
but it crash and exit.
Welcome any comment
Thanks interdev
you released playa and it's dealloced. If musicPlaya is a retained property, you are only accessing the set message when you use
self.musicPlayer = playa;
You did the same thing later with musicPlayer
-- the method you called returned an autoreleased object. You need to retain it -- probably by using the set message through self.musicPlayer
syntax.
The easiest way to find problems like this is to run a Build and Analyze -- I'm pretty sure it would flag playa as being released too many times. Another good way is by using NSZombiesEnabled which I described how to do on my blog (see Tip #1)
http://www.loufranco.com/blog/files/debugging-memory-iphone.html
UPDATE: to explain further:
You make an instance variable with
MPMusicPlayerController* musicPlayer;
and then a property with
@property (retain, nonatomic) MPMusicPlayerController* musicPlayer;
Later in your code, you might think that
musicPlayer = playa;
is the same as
self.musicPlayer = playa;
Because the equivalent thing in Java, C++, and C# (and other languages) is. It IS NOT the same.
In Objective-C. The @property line generated two messages, getmusicPlayer and setmusicPlayer. You could use
[self setmusicPlayer: playa]
and that would automatically retain playa for you. self.musicPlayer = playa
is a synonym for that.
Using just musicPlayer
without self bypasses the set message (and the retain) and just assigns directly to the instance variable.
You can avoid this by doing this instead
@interface ClassName : NSObject
{
MPMusicPlayerController* _musicPlayer;
}
@property(retain, nonatomic) MPMusicPlayerController* musicPlayer;
and then
@synthesize musicPlayer = _musicPlayer;
Then, always use self.musicPlayer
for assignment to make sure to get the retain. If you accidentally leave off the self, you'll get a compiler error.
精彩评论