2015-01-08 3 views
3

Привет Я играю видео на своем UITableViewCells с помощью AVPlayer, он отлично работает на iOS 7, но в iOS8 он сбой со следующей ошибкой.Проблема AVPlayerItem addobserver в iOS8

 'An instance 0x7c01b000 of class AVPlayerItem was deallocated while key value observers were still registered with it. 

Вот мой код

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
     { 

      ......... 
      ......... 

     if(cell.videoPlayer!= nil && cell.videoPlayer.currentItem != nil) 

      { 
       [cell.videoItem removeObserver:self forKeyPath:@"playbackBufferEmpty" context:nil]; 
       [cell.videoItem removeObserver:self forKeyPath:@"playbackLikelyToKeepUp" context:nil]; 

       } 
    cell.videoPlayer = [AVPlayer playerWithPlayerItem:cell.videoItem]; 
    cell.avLayer = [AVPlayerLayer playerLayerWithPlayer:cell.videoPlayer]; 
    cell.videoPlayer.actionAtItemEnd = AVPlayerActionAtItemEndNone; 

    [cell.videoItem addObserver:self forKeyPath:@"playbackBufferEmpty" options:NSKeyValueObservingOptionInitial context:nil]; 
    [cell.videoItem addObserver:self forKeyPath:@"playbackLikelyToKeepUp" options:NSKeyValueObservingOptionInitial context:nil]; 

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(itemDidBufferPlaying:) name:AVPlayerItemPlaybackStalledNotification object:nil]; 

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(itemDidFinishPlaying:) name:AVPlayerItemDidPlayToEndTimeNotification object:nil]; 

    cell.avLayer.frame = CGRectMake(5, 9, 310, 310); 
    [cell.contentView.layer addSublayer: cell.avLayer]; 
    [ cell.videoPlayer play]; 
    [cell.contentView addSubview:cell.videoActivity]; 


    return cell; 
    } 



    -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object 
       change:(NSDictionary *)change context:(void *)context { 




     NSArray* cells = homeTabl.visibleCells; 

     for (HomeCell* cell in cells) { 

     if (object == cell.videoItem && [keyPath isEqualToString:@"playbackBufferEmpty"])     { 

    if (cell.videoItem.playbackBufferEmpty) { 

     NSLog(@"buffering"); 
     cell.videoActivity.hidden = NO; 



     } 
    } 

     else if (object == cell.videoItem && [keyPath isEqualToString:@"playbackLikelyToKeepUp"]) 
    { 
     if (cell.videoItem.playbackLikelyToKeepUp) 
     { 


     cell.videoActivity.hidden = YES; 
     [cell.videoPlayer play]; 

      } 
     } 

     } 

    } 


-(void)scrollViewDidScroll:(UIScrollView *)aScrollView { 

    NSArray* cells = homeTabl.visibleCells; 

    for (HomeCell* cell in cells) { 

    [cell.videoPlayer pause]; 
    [cell.avLayer removeFromSuperlayer]; 
    cell.videoPlayer = nil; 
    cell.videoItem = nil; 


    } 

Что может быть причиной? Я прошел этот SO-вопрос, но я не смог реализовать это в своих кодах. Пожалуйста, помогите мне исправить это.

ответ

4

Удаление наблюдателей - одна из самых ярких областей в iOS в моем опыте. Вам очень важно сбалансировать вызовы для AddObserver с помощью RemoveObserver. Я нашел отказоустойчивый способ сделать это, чтобы поместить любые вызовы AddObserver в метод Init объекта, а затем сбалансировать их с вызовами RemoveObserver в методе Dealloc. В вашем случае это будет в вашем подклассе videoItem. (Этот код не установлен)

- (id) initWithOwner:(id)owner 
{ 
    self = [super init]; 
    if(self) { 
     _owner = owner; 
     [self addObserver:_owner forKeyPath:@"playbackBufferEmpty" options:NSKeyValueObservingOptionInitial context:nil]; 
    } 
    return self; 
} 

- (void) dealloc 
{ 
    [self removeObserver:_owner forKeyPath:@"playbackBufferEmpty" context:nil]; 
} 

Я не уверен, где объявлено videoItem, но в основном вы создаете новый класс с именем VideoItem и в ней создать новый Инициализатор под названием initWithOwner :. В вашем cellForRowAtIndexPath: метод, при создании своей новой ячейки можно также создать экземпляр VideoItem и передать себя как владелец

self.videoItem = [[VideoItem alloc] initWithOwner:self]; 

Без больше кода я не могу указать это более подробно. Вы также можете подумать о форматировании кода сначала в xcode, а затем разрезать и вставить его в SO, чтобы сохранить его более аккуратным.

+0

Hi @amergin - Спасибо за помощь. Не могли бы вы описать немного больше, где я могу использовать приведенный выше код. Я объявил VideoItem в своей таблице. Можете ли вы проверить мой код. –

+0

@NITHINSHAHRUKH немного изменил мой ответ. Без вашего кода я не могу быть более ясным, извините. – amergin

Смежные вопросы