最初に AVPlayerItem を NSPurgeableData オブジェクトに格納し、そこから再生します。データオブジェクトを NSCache オブジェクトに保存して、再生後または接続が切断されたときにオブジェクトをメモリから自動的に削除し、以前の AVPlayerItem が新しいものに置き換えられます (これらすべては、あなたが説明する特定の問題)。開始するためのコードを次に示します。
void (^cachePlayerItem)(AVPlayerItem *, NSCache *, NSString *) = ^(AVPlayerItem *playerItem, NSCache *cache, NSString *key) {
NSURL *fileURL = [(AVURLAsset *)playerItem.asset URL];
NSPurgeableData *data = [NSPurgeableData dataWithContentsOfURL:fileURL];
[data beginContentAccess];
[cache setObject:data forKey:key];
[data endContentAccess];
[data discardContentIfPossible];
};
このブロックを実装ファイルの任意の場所に配置し、ヘッダー ファイルで次のように定義します。
typedef void (^cachePlayerItemBlock)(AVPlayerItem *, NSCache *, NSString *);
メソッド内で次のように呼び出します。
cachePlayerItem(playerItem, playerItems, phAsset.localIdentifier);
一方、playerItem は AVPlayerItem であり、playerItems は NSCache キャッシュであり、AVPlayerItem を取得しているアセットの種類に応じて、それに固有の何らかの識別子 (または上記の例では関連するアセット) です。
ちなみに、それに応じて AppDelegate でキャッシュを設定しました。
- (NSCache *)thumbnailCache {
__block NSCache *t = self->_thumbnailCache;
if (!t) {
t = [[NSCache alloc] init];
[t setName:@"Thumbnail Cache"];
[t setEvictsObjectsWithDiscardedContent:TRUE];
[t setCountLimit:self.assetsFetchResults.count];
self->_thumbnailCache = t;
}
return t;
}
これにより、キャッシュへのグローバル アクセスだけでなく、キャッシュの 1 つのインスタンスも保証されます。これは、サイズが大きくなる可能性があるため、AVPlayerItem をキャッシュする場合に特に重要です。
AppDelegate でグローバルにアクセス可能なキャッシュを作成するには、これらをヘッダー ファイルと実装ファイルにそれぞれ追加します。
+ (AppDelegate *)sharedAppDelegate;
...と:
+ (AppDelegate *)sharedAppDelegate
{
return (AppDelegate *)[[UIApplication sharedApplication] delegate];
}
他のクラス ファイルでキャッシュを参照するには、AppDelegate ヘッダー ファイルをインポートし、必要に応じて、AppDelegate の sharedApplication メソッドへのショートカットを作成します。
#import "AppDelegate.h"
#define AppDelegate ((AppDelegate *)[[UIApplication sharedApplication] delegate])
そうすることで、キャッシュは次の方法で参照できます...:
AppDelegate.thumbnailCache
...それ以外の:
AppDelegate.sharedAppDelegate.thumbnailCache