AVPlayer was deallocated while key value observers were still registered with it

I am creating a simple media player app. My App is crashed when first link is played and I clicked second link in uitableview.

- (void)viewDidLoad {
        [super viewDidLoad];
        arrURL = [NSArray arrayWithObjects: @"http://yp.shoutcast.com/sbin/tunein-station.pls?id=148820", @"http://www.kcrw.com/pls/kcrwmusic.pls",@"http://yp.shoutcast.com/sbin/tunein-station.pls?id=175821",@"http://yp.shoutcast.com/sbin/tunein-station.pls?id=148820",@"http://yp.shoutcast.com/sbin/tunein-station.pls?id=70931",nil];
        url = [[NSURL alloc] init];    
    }

    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

        return [arrURL count];
    }

- (UITableViewCell *)tableView:(UITableView *)tableView
         cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *MyIdentifier = @"MyIdentifier";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
    if (cell == nil)
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier] ;
    }
     cell.textLabel.text = [arrURL objectAtIndex:indexPath.row];
    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    selectedSongIndex = indexPath.row;
    url = [[NSURL alloc] initWithString:[arrURL objectAtIndex:indexPath.row]];
    [self setupAVPlayerForURL:url];
    [player play];

    //[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
- (IBAction)btnPlay_Click:(id)sender {

    [player play];
    AVPlayerItem *item = player.currentItem;
    [item addObserver:self forKeyPath:@"timedMetadata" options:NSKeyValueObservingOptionInitial| NSKeyValueObservingOptionNew| NSKeyValueObservingOptionOld| NSKeyValueObservingOptionPrior context:nil];
}
- (IBAction)btnPause_Click:(id)sender {

    [player pause];
}

- (IBAction)btnStop_Click:(id)sender {

    [player pause];
}
-(void) setupAVPlayerForURL: (NSURL*) url1 {
    AVAsset *asset = [AVURLAsset URLAssetWithURL:url1 options:nil];
    AVPlayerItem *anItem = [AVPlayerItem playerItemWithAsset:asset];

    player = [AVPlayer playerWithPlayerItem:anItem]; **//Application Crashed**
    [player addObserver:self forKeyPath:@"status" options:0 context:nil];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    if([keyPath isEqualToString:@"timedMetadata"])
    {
        AVPlayerItem *item = (AVPlayerItem *)object;
        NSLog(@"Item.timedMetadata: %@",item.timedMetadata);
        NSLog(@"-- META DATA ---");
        //        AVPlayerItem *pItem = (AVPlayerItem *)object;
        for (AVMetadataItem *metaItem in item.timedMetadata) {
            NSLog(@"meta data = %@",[metaItem commonKey]);
            NSString *key = [metaItem commonKey]; //key = publisher , key = title
            NSString *value = [metaItem stringValue];
            NSLog(@"key = %@, value = %@", key, value);
            if([[metaItem commonKey] isEqualToString:@"title"])
            {
                self.lblTitle.text = [metaItem stringValue];
            }
        }
    }
    if (object == player && [keyPath isEqualToString:@"status"]) {
        if (player.status == AVPlayerStatusFailed) {
            NSLog(@"AVPlayer Failed");
        } else if (player.status == AVPlayerStatusReadyToPlay) {
            NSLog(@"AVPlayer Ready to Play");
        } else if (player.status == AVPlayerItemStatusUnknown) {
            NSLog(@"AVPlayer Unknown");
        }
    }
}

I got this message when App crashed.

  • Allow “auto lock” while video is being played
  • Timeline Progress bar for AVPlayer
  • AVFoundation audio processing using AVPlayer's MTAudioProcessingTap with remote URLs
  • AVPlayer not playing from music library
  • AVPlayer “freezes” the app at the start of buffering an audio stream
  • Play multiple Audio Files with AVPlayer
  • *** Terminating app due to uncaught exception ‘NSInternalInconsistencyException’, reason: ‘An instance 0x165297c0 of
    class AVPlayer was deallocated while key value observers were still
    registered with it. Current observation info:
    ( Context: 0x0, Property: 0x1661d5d0> )’

    Application crashed only in IOS 8 in IOS 7 works fine.
    What I am doing wrong??

    3 Solutions Collect From Internet About “AVPlayer was deallocated while key value observers were still registered with it”

    I had a similar problem. It worked fine in iOS 7, and now it crashes in iOS 8.

    The solution was to remove the observer, before releasing the object.

    When you replace or allocate a new object for a member, you’re releasing the old object, so you need to remove the observer first :

    -(void) setupAVPlayerForURL: (NSURL*) url1 {
        AVAsset *asset = [AVURLAsset URLAssetWithURL:url1 options:nil];
        AVPlayerItem *anItem = [AVPlayerItem playerItemWithAsset:asset];
        if (player != nil)
            [player removeObserver:self forKeyPath:@"status"];
        player = [AVPlayer playerWithPlayerItem:anItem]; 
        [player addObserver:self forKeyPath:@"status" options:0 context:nil];
    }
    

    And similarly in btnPlayClick ( in case it is pressed without btnStop_Click being pressed) :

    - (IBAction)btnPlay_Click:(id)sender {
         if (player != nil && [player currentItem] != nil)
             [[player currentItem] removeObserver:self forKeyPath:@"timedMetadata"];
        AVPlayerItem *item = player.currentItem;
        [item addObserver:self forKeyPath:@"timedMetadata" options:NSKeyValueObservingOptionInitial|     NSKeyValueObservingOptionNew| NSKeyValueObservingOptionOld| NSKeyValueObservingOptionPrior context:nil];
        [player play];
    }
    

    When using KVO you must balance calls to addObserver:forKeyPath:options:context: with calls to removeObserver:forKeyPath: (see the KVO programming guide).

    Try removing the view controller as an observer when the stop button is tapped e.g.

    - (IBAction)btnStop_Click:(id)sender {
        [[player currentItem] removeObserver:self forKeyPath:@"timedMetadata"];
    }
    
    -(void)viewWillDisappear:(BOOL)animated
    {
    [self.player removeObserver:self forKeyPath:@"status" context:nil];
    }