PIYO - Tech & Life -

past the lifetime of its owning ALAssetsLibrary

ALAssetsLibaryで取得したALAssets*のオブジェクトを使おうとするとこんなエラーメッセージが出ることがある。

invalid attempt to access <ALAssetPrivate: 0x16eb5630> past the lifetime of its owning ALAssetsLibrary

起動時にALAssetを読み込んでおき、あとで使うためにNSMutableArrayか何かで保持しておくとする。そのとき例えばこういうコードを書く。すると↑のようなエラーが出て写真などの情報を取ってこれないという事態になる。

- (void)loadAssets {
    _assets = [NSMutableArray new];
    
    ALAssetsLibrary *assetsLibrary = [[ALAssetsLibrary alloc] init];
    [assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
        if(!group) return;
        [group enumerateAssetsWithOptions:NSEnumerationReverse usingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
            [self.assets addObject:result];
        }];
    } failureBlock:nil];
}

どうやらこのエラーは使おうとしているALAssets*を返してくれたALAssetsLibraryが既にいなくなっているというような意味合いらしい。先ほどのコードではALAssetsLibraryがメソッドのローカルスコープにあり、そのスコープ外ではALAssets*を使えないようだ。

ALAssetsLibraryをプロパティとして持つことでこの問題は回避できる。

@interface ViewController()
@property (nonatomic, strong) ALAssetsLibrary *assetsLibrary;
@end

- (void)loadAssets {
    _assets = [NSMutableArray new];

    _assetsLibrary = [[ALAssetsLibrary alloc] init];

    // 略
}