Подтвердить что ты не робот

AVPlayer вылетает после нескольких воспроизведений -

Я пытаюсь создать приложение, которое воспроизводит видео из файла с помощью AVFoundation. Видеоролики отображаются в виде, доступ к которому осуществляется нажатием на строку в родительском представлении таблицы. У реального приложения будет видео для каждой строки, но на данный момент я использую только один для тестирования.

При запуске на симуляторе приложение работает нормально, но при запуске на устройстве (под ios 5.1) видео воспроизводится нормально примерно в 5 раз, а затем непредсказуемо разбивается по множеству способов. Чаще всего видеозагрузка загружается, но само видео не воспроизводится, но иногда Я получаю EXC_BAD_ACCESS в потоке coremedia.remote, жалуясь на объекты, которые выделяются без пула авторезистов. Я добавил блок @autoreleasepool, обертывающий код, запускающий AVPlayer, но это, похоже, не помогает.

Мне интересно, происходит ли GCD, создавая несколько потоков в главной очереди для воспроизведения элементов, но они не заканчиваются.

Итак, ключевой вопрос - как я могу очистить лишние потоки GCD, на которых работает AVPlayer? если пользователь нажимает кнопку "Назад" в режиме просмотра видео Насколько это возможно, я следовал примеру кода, представленного в документации Apple AVFoundation здесь Я добавил несколько протоколов и (как упоминалось выше) блок @autoreleasepool внутри одного из блоков GCD, кроме того, что я не изменил код.

Метод viewDidLoad выглядит следующим образом:

-(void)viewDidLoad{   
[super viewDidLoad];

NSURL *fileURL = [[NSBundle mainBundle] URLForResource:@"TestLapCar2Vid" withExtension:@"m4v"];
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:fileURL options:nil];
NSString *tracksKey = @"tracks";

[asset loadValuesAsynchronouslyForKeys:[NSArray arrayWithObject:tracksKey] completionHandler:
 ^{
     dispatch_async(dispatch_get_main_queue(),
     ^{
         @autoreleasepool {
         NSError *error = nil;
             AVKeyValueStatus status = [asset statusOfValueForKey:tracksKey error:&error];

             if(status == AVKeyValueStatusLoaded){
                 avPlayerItem = [AVPlayerItem playerItemWithAsset:asset];
                 [avPlayerItem addObserver:self forKeyPath:@"status"
                                   options:0  context:&ItemStatusContext];

                 [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(playerItemDidReachEnd:)
                                                             name:AVPlayerItemDidPlayToEndTimeNotification object:avPlayerItem];

                 avPlayer = [AVPlayer playerWithPlayerItem:avPlayerItem];
                 [videoView setPlayer:avPlayer];
                 NSLog(@"Asset loaded");
                 [avPlayer play];
             }
             else{
                 NSLog(@"The asset tracks were not loaded");
             }

         }
     });
 }];    

}

Метод viewWillDisappear:

-(void)viewWillDisappear:(BOOL)animated{
NSLog(@"view will disappear called");
[super viewWillDisappear:animated];
dispatch_async(dispatch_get_main_queue(), 
    ^{
        [avPlayer pause];
        [avPlayerItem removeObserver:self forKeyPath:@"status"];
        [[NSNotificationCenter defaultCenter]removeObserver:self];
        NSLog(@"Race timeline nav controller has %d sub controllers",self.navigationController.childViewControllers.count);
        avPlayerItem = nil;
        avPlayer = nil;
        videoView = nil;
        dataStore = nil;
        pkReader = nil;
        receivedData = nil;
        revDial = nil;
        speedDial = nil;
        mapView = nil;
        throttle = nil;
        NSLog(@"releasing stuff");
    });

}

Я боролся с этим в течение большей части сегодняшнего дня - любая помощь была бы с благодарностью принята

4b9b3361

Ответ 1

Сначала вы должны удалить из супервизора, так как это уменьшит количество удержаний на единицу, и ARC позаботится о вас.

как это

[videoView removeFromSuperview];
[self setVideoView:nil];

Ответ 2

Может быть, вы оставите свой видеофайл в каком-то месте? Потому что, если вы это сделаете, ваш avPlayerItem и avPlayer останутся в живых, и в соответствии с этой > темой вы подошли к ограничению iOS для "рендеринга конвейера" с 4-мя видео, остающимися в памяти.

Помните, что установка var в nil фактически не освобождает базовый объект. Итак, ваш

videoView = nil;

может иметь нулевой эффект.