Search code examples
iosobjective-cavaudiosessionavaudiorecorder

Why delegate method is not called - iOS


I have an AudioRecorder class for recording audio, and I have the following code:

_recorder = [[AVAudioRecorder alloc] initWithURL:audioFileURL settings:recordSettings error:&error];
        
if (_recorder && [_recorder prepareToRecord]) {
    [_recorder recordForDuration:10.0]; // Record for 10 seconds
    [_recorder setDelegate:self];
    [_recorder setMeteringEnabled:YES];
}

So, here self is the AudioRecorder class which is declare as:

@interface AudioRecorder : NSObject <AVAudioRecorderDelegate>
    
@property AVAudioRecorder *recorder;
@property AVAudioSession *session;

@end

Then I have this callback method that should (but is not) called after the 10 seconds registration:

- (void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag {}

Why is this not called after the 10 sec registration?


Solution

  • There are two common reason which make delegate methods not being called.

    The first one is not setting the delegate property or implementing a wrong method (ie, typo on the method). Which is not the case here.

    The second one, is that the object is released (from memory) too soon. In other words, the delegate method will be called later (here ~10 seconds after), and delegate properties are almost always weakly reference to avoid memory issue (cycle), when the object need to call its delegate method, the object doesn't exist anymore. That's your issue. The small difference here, it's that's the parent of the delegate that is released too soon.
    Because _recorder is a property of AudioRecorder, so as long as the AudioRecorder instance exists, it will still be here and let the delegate method be called.
    But, the AudioRecorder is a local variable, so it will cease to exists after its scope (~after the next closing }).

    So you need to make AudioRecorder a property of the object holding it.