robz S
robz S

Reputation: 25

remove observer in dealloc with an object

i've an object declared as:

AVQueuePlayer *queuePlayer;

in code i've added an observer:

- (void) playStreamedTrack: (Track *) track {

[queuePlayer addObserver:self forKeyPath:@"status" options:0 context:nil];

        [queuePlayer addPeriodicTimeObserverForInterval:CMTimeMakeWithSeconds(1, NSEC_PER_SEC)
                                                  queue:nil
                                             usingBlock:^(CMTime time) {
                                                 progress = time.value/time.timescale;
                                             }];
}

i've tried to remove the observer as follow, but not work

- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];

    [queuePlayer removeObserver:self forKeyPath:@"status" context:nil];
}

how can i remove the observer?

Upvotes: 0

Views: 4589

Answers (1)

Phil
Phil

Reputation: 2794

As stated by [AVPlayer addPeriodicTimeObserverForInterval] doc, you must retain the return value in order to be able to remove the observer later on.

So you need to add a property in your class interface

@property (nonatomic, strong) id playerObserver;

And store the returned value when you create the observer

if(self.playerObserver)
    [queuePlayer removeTimeObserver:self.playerObserver];
self.playerObserver = [self.queuePlayer addPeriodicTimeObserverForInterval:CMTimeMakeWithSeconds(1, NSEC_PER_SEC)
                                                                     queue:nil
                                                                usingBlock:^(CMTime time) {
                                                                    progress = time.value/time.timescale;
                                                                }];

In the dealloc, you can then release the observer

- (void)dealloc {    
    [queuePlayer removeTimeObserver:self.playerObserver];
    [queuePlayer removeObserver:self forKeyPath:@"status" context:nil];
}

Please, also note that in your block, you might need to use weak reference to your instance in order to avoid retain cycle. If your "progress" variable is actually an instance variable, you must use a weak reference like this one :

__typeof__(self) __weak weakSelf = self;

self.playerObserver = [self.queuePlayer addPeriodicTimeObserverForInterval:CMTimeMakeWithSeconds(1, NSEC_PER_SEC)
                                                                     queue:nil
                                                                usingBlock:^(CMTime time) {
                                                                    weakSelf.progress = time.value/time.timescale;
                                                                }];

Upvotes: 3

Related Questions