AVPlayer продолжает играть после удаления ViewController из NavigationController - PullRequest
22 голосов
/ 10 ноября 2011

Так что я использую ARC в своем проекте, и когда я добавляю AVPlayerLayer, он работает просто отлично, но когда я извлекаю UIViewController из моего UINavigationItem, видео продолжает воспроизводиться в фоновом режиме. Кто-нибудь знает, как бы вы справились с этим? Кажется, что-то легкое, я просто пропускаю Вот код, который у меня есть для первоначальных реализаций.

self.currentItem = [[AVPlayerItem alloc] initWithURL:url];

self.player = [[AVPlayer alloc]initWithPlayerItem:self.currentItem];
self.avPlayerLayer = [AVPlayerLayer playerLayerWithPlayer:player];

self.avPlayerLayer.bounds = self.view.bounds;
self.avPlayerLayer.frame = CGRectMake(0,55, 1024, 670);

self.view.backgroundColor = [UIColor clearColor];

[self.view.layer addSublayer:avPlayerLayer];

Также вот как я определил свойства.

@property (strong) AVPlayer *player;
@property (strong) AVPlayerLayer *avPlayerLayer;
@property (strong) AVPlayerItem *currentItem;

Может быть, это тоже совершенно неправильно. Я не совсем уверен, когда использовать (сильный) против (слабый). В любом случае заранее благодарю за любую помощь.

Ответы [ 3 ]

14 голосов
/ 10 ноября 2011

Если avPlayerLayer - единственный класс, взаимодействующий с avPlayer, вам не нужно сохранять ссылку на него со свойством в классе, который вы используете для его представления (если этот класс не использует его вне кода, который вы используете общий). На самом деле, возможно, именно поэтому он не работает так, как вы ожидаете.

Причина, по которой клип продолжает воспроизводиться (я думаю), заключается в том, что игрока не освобождают. Вы создаете его, владеете им со свойством strong в своем классе, чем оно снова принадлежит классу AVPlayerLayer, которому вы его передаете. Поэтому, когда AVPlayerLayer освобождается, AVPlayer теряет одного владельца. Но у него все еще есть владелец (ваш класс), поэтому он не освобожден и продолжает играть. Решение здесь состоит в том, чтобы полностью избавиться от вашей собственности на * avPlayer. Тебе это не нужно. Создайте AVPlayer и передайте его AVPlayerLayer. Это должно быть все, что нужно.

Что-то еще, что вы могли бы сделать, чтобы исправить поведение, но не проблему, позвоните:

[avPlayer pause]

В методе dealloc вашего AVPlayerLayer.

Re: Сильные и слабые ссылки: Сильная ссылка подразумевает владение. Поскольку ARC управляет памятью, она будет выполнять все [сохранение объекта] и [освобождение объекта], что вы ранее делали в коде ИЛИ, что вы сделали бы со свойствами, то есть:

@property (retain) NSObject *iAmRetainedWhenProperyIsAssigned;

Так что теперь с ARC, мы, простые пользователи, не используем такие слова, как retain или release в коде или при определении свойств. Но мы все еще разрабатываем программное обеспечение. ARC умна, но недостаточно умна, чтобы определить архитектурные последствия отношений, которые мы определяем. Еще нужно сказать, что класс «владеет» ссылкой на объект, на который ссылается свойство. Что сокращает нас, в самых основных терминах:

(сильный) означает для ARC, что (сохранить) означало для свойств предварительно ARC (принадлежит / сохраняется)

(слабый) означает для ARC, что (назначать) означало для свойств pre-ARC (не принадлежит / не сохраняется)

13 голосов
/ 09 февраля 2012

Может быть, вы не сделали паузу. Сделайте это, а затем удалите слой и обнулите player.

[player Pause];
[player removefromsuperlayer];
player = nil;
1 голос
/ 26 февраля 2014

Если вы хотите остановить загрузку AVPlayerItem, используйте removeAllItems AVQueuePlayer, а затем повторно инициализируйте его.

  [self.avPlayer removeAllItems];
  self.avPlayer = [AVQueuePlayer playerWithURL:[NSURL URLWithString:@""]];
  self.avPlayer = nil;

Это остановит загрузку текущего элемента - это единственный способ, который я нашел для этого.

...