Problem with AVAudioplayer or delegation received early

I make a counting game for children. At the beginning, the child is asked to find several items, for example: "Can you find five bicycles." All this is randomly collected from separate arrays of sounds with parts of the sentence: "You can find" + "5" + "bikes" = three separate mp3s. When the child begins to click on objects, they disappear and the voice is counted. β€œ1”, β€œ2”, β€œ3”, β€œ4”, β€œ5”, and at the end β€œbicycles”.

I use the audioPlayerDidFinishPlaying: delegate method to combine sounds, and this works great ... in most cases. But sometimes the application crashes with the "bad_access" error. After using NSZombie, I got: - [AVAudioPlayer performSelector: withObject:]: message sent to a freed instance

I think this is due to the fact that the audio player or delegate itself is released prematurely.

I always use this function to play sounds:

-(void)spillVoice:(NSString*) filnavn{
NSString *audioFilePath=[[NSBundle mainBundle] pathForResource:filnavn ofType:@"mp3"];
NSURL *audioFileURL=[NSURL fileURLWithPath:audioFilePath];
self.voicespiller=[[[AVAudioPlayer alloc] initWithContentsOfURL:audioFileURL error:nil] autorelease];
self.voicespiller.delegate=self;
[self.voicespiller prepareToPlay];
[self.voicespiller play];
NSLog(@"spiller lyden");

}

And here is the delegate (he performs different actions based on the fact that the sound has finished):

-(void)audioPlayerDidFinishPlaying:(AVAudioPlayer*)which_player successfully:(BOOL)the_flag{
NSLog(@"ny lyd?");
[self.jenteBilde stopAnimating];
if(self.etterLyd==@"ingenting"){
    NSLog(@"ingenting");    
}
else if(self.etterLyd==@"lesobjekt"){
    NSLog(@"lesobjekt");
    self.etterLyd=@"ros";
    [self spillVoice:[self.objektNedArray objectAtIndex: [self.objektnr intValue]]];
    [self.jenteBilde startAnimating];
}
else if(self.etterLyd==@"introtall"){
    NSLog(@"introtall");
    self.etterLyd=@"introobjekt";
    [self spillVoice:[self.telleOppArray objectAtIndex: [self.tilfeldig intValue]]];
    [self.jenteBilde startAnimating];
}
else if(self.etterLyd==@"introobjekt"){
    NSLog(@"introobjekt");  
    self.etterLyd=@"ingenting";
    [self spillVoice:[self.objektOppArray objectAtIndex: [self.objektnr intValue]]];
    [self.jenteBilde startAnimating];
}
else if(self.etterLyd==@"ros"){
    NSLog(@"ros");  
    NSMutableArray *rosArray=[[NSMutableArray alloc] initWithObjects:@"TT_flott",@"TT_bravo",@"TT_fint",@"TT_du_er_kjempeflink",@"TT_hurra",@"TT_helt_riktig",nil];
    int result=(arc4random() % (rosArray.count));
    self.etterLyd=@"ingenting";
    [self spillVoice:[rosArray objectAtIndex: result]];
    [self.jenteBilde startAnimating];
}

}

It seems to me that the abstract of AVaudioplayers gets too early, although the sound is not yet finished. I tried not to auto-implement, but explicitly highlighted the delegate function. But the problem is that the sound does not always get to the end (when the child finds a new element before the voice finishes reading) ...

- . !

+3
1

AVAudioPlayer, . - voicespiller :

-(void)spillVoice:(NSString*)filnavn {
    // stop any previous player
    [self.voicespiller stop];

    NSString *audioFilePath=[[NSBundle mainBundle] pathForResource:filnavn ofType:@"mp3"];
    NSURL *audioFileURL=[NSURL fileURLWithPath:audioFilePath];

    [self setVoicespiller:[[AVAudioPlayer alloc] initWithContentsOfURL:audioFileURL error:nil] autorelease];
    self.voicespiller.delegate=self;
    [self.voicespiller prepareToPlay];
    [self.voicespiller play];
    NSLog(@"spiller lyden");
}

([self setVoicespiller:...]), , . [voicespiller release] dealloc.

0

Source: https://habr.com/ru/post/1761891/


All Articles