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

AVPlayer продолжает воспроизводиться после удаления ViewController из NavigationController

Итак, я использую 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;

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

4b9b3361

Ответ 1

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

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

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

[avPlayer pause]

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

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

@property (retain) NSObject *iAmRetainedWhenProperyIsAssigned;

Итак, теперь с ARC, мы, простые пользователи, не используем такие слова, как сохранение или выпуск в коде или при определении свойств. Но мы все еще разрабатываем программное обеспечение. ARC является умным, но недостаточно умным, чтобы вывести архитектурные последствия отношений, которые мы определяем. По-прежнему нужно сказать, что класс "владеет" ссылкой на объект, к которому относится свойство. Что сокращает нас, в самых основных терминах:

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

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

Ответ 2

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

[player Pause];
[layer removefromsuperlayer];
player = nil;

Ответ 3

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

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

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