web-dev-qa-db-ja.com

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;

多分それも完全に間違っています。 (強)vs(弱)をいつ使用するかは正確にはわかりません。どのような場合でも、事前に助けをお願いします。

24
James Parker

AvPlayerLayerがavPlayerと対話する唯一のクラスである場合、それを表示するために使用しているクラスのプロパティを使用して、その参照を維持する必要はありません(このクラスが共有したコードの外部で使用しない限り)。実際、これがおそらく期待どおりに機能しない理由です。

クリップが引き続き再生される理由(私はそう思います)は、プレーヤーが割り当て解除されていないためです。これを作成し、クラスのstrongプロパティを使用して所有しますが、それを渡したAVPlayerLayerクラスによって再び所有されます。したがって、AVPlayerLayerの割り当てが解除されると、AVPlayerは1人の所有者を失います。ただし、所有者(クラス)がまだあるため、割り当ては解除されず、引き続き再生されます。ここでの解決策は、* avPlayerの所有プロパティを完全に取り除くことです。あなたはそれを必要としません。 AVPlayerを作成し、AVPlayerLayerに渡します。それだけで十分です。

動作は修正できるが問題は修正できない他の方法で、次のように呼び出します。

[avPlayer pause]

AVPlayerLayerのdeallocメソッド内。

Re:強い参照と弱い参照:強い参照は所有権を意味します。 ARCはメモリを管理しているため、以前にコードで実行した[オブジェクトの保持]と[オブジェクトの解放]をすべて実行しますORプロパティで実行した場合)つまり:

@property (retain) NSObject *iAmRetainedWhenProperyIsAssigned;

したがって、ARCでnowを使用すると、単純なユーザーはコード内で、またはプロパティを定義するときに、retainまたはreleaseなどの単語を使用しません。しかし、私たちはまだソフトウェアを設計しています。 ARCは賢いですが、私たちが定義している関係のアーキテクチャ上の影響を推測するほど賢くはありません。それでも、クラスが、プロパティが参照するオブジェクトへの参照を「所有」していることを通知する必要があります。これは、最も基本的な用語で私たちを減らします:

(強い)ARCにとって、ARC以前のプロパティ(所有/保持)に対する(保持)の意味

(弱い)とは、ARCに対して、(割り当てられていない)ARC以前のプロパティを作成することの意味(所有されていない/保持されていない)を意味します

15
isaac

たぶん、あなたは一時停止しませんでした。それを行ってからレイヤーを削除し、playerを無効にします。

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

AVPlayerItemのロードを停止する場合は、AVQueuePlayerのremoveAllItemsを使用してから、再初期化します。

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

これにより、現在のアイテムの読み込みが停止します。これが、これを実現するための唯一の方法です。

1
BigCheesy