我的应用程序的一部分有一个照片浏览器,有点类似于Apple的照片应用程序,有一个初始视图控制器来浏览照片缩略图和一个点击照片时显示的详细视图。
我正在使用ALAssetsLibrary来访问照片,并将一组ALAsset URL传递给我的详细视图控制器,以便您可以从一张照片滑动到下一张照片。
一切都很好,直到我从一张照片到另一张照片(在详细视图控制器中)滑动时收到ALAssetsLibraryChangedNotification,这通常会导致崩溃:
通知:资产库改变了//我自己的NSLog for 发生通知
在我开始重新加载资产时加载资产... //我自己的NSLog 缩略图浏览器
断言失败:( size == bytesRead),函数 - [ALAssetRepresentation _imageData],file /SourceCache/AssetsLibrary/MobileSlideShow-1373.58.1/Sources/ALAssetRepresentation.m, 第224行。
它崩溃的特定代码行是调用[currentRep metadata],如下所示:
- (void)someMethod {
NSURL *assetURL = [self.assetURLsArray objectAtIndex:index];
ALAsset *currentAsset;
[self.assetsLibrary assetForURL:assetURL resultBlock:^(ALAsset *asset) {
[self performSelectorInBackground:@selector(configureDetailViewForAsset:) withObject:asset];
} failureBlock:^(NSError *error) {
NSLog(@"failed to retrieve asset: %@", error);
}];
}
- (void)configureDetailViewForAsset:(ALAsset *)currentAsset {
ALAssetRepresentation *currentRep = [currentAsset defaultRepresentation];
if (currentAsset != nil) {
// do some stuff
}
else {
NSLog(@"ERROR: currentAsset is nil");
}
NSDictionary *metaDictionary;
if (currentRep != nil) {
metaDictionary = [currentRep metadata];
// do some other stuff
}
else {
NSLog(@"ERROR: currentRep is nil");
}
}
我理解一旦收到通知,它会对ALAsset和ALAssetRepresentation对象的任何引用失效......但是我应该如何处理它在尝试访问它的过程中无效的情况?
我已经尝试设置一个BOOL,当收到通知完全中止并阻止[currentRep元数据]被调用时,但是即使这样也不会每次都捕获它:
if (self.receivedLibraryChangeNotification) {
NSLog(@"received library change notification, need to abort");
}
else {
metaDictionary = [currentRep metadata];
}
我能做些什么吗?在这一点上,我几乎已经准备好放弃使用ALAssetsLibrary框架了。
(注意Apple dev论坛上这个未解决的帖子描述了同样的问题:https://devforums.apple.com/message/604430)
答案 0 :(得分:6)
问题似乎就在这里:
[self.assetsLibrary assetForURL:nextURL
resultBlock:^(ALAsset *asset) {
// You should do some stuff with asset at this scope
ALAssetRepresentation *currentRep = [asset defaultRepresentation];
// Assume we have a property for that
self.assetRepresentationMetadata = [currentRep metadata];
...
// assume we have a method for that
[self updateAssetDetailsView];
}
failureBlock:^(NSError *error) {
NSLog(@"failed to retrieve asset: %@", error);
}];
获得用户资产后,最好通过向详细信息控制器子视图提供必要的数据或通过缓存以供以后使用来复制资产信息。避免ALAsset失效问题会有所帮助。当通知ALAssetsLibraryChangedNotification发送时,您可能需要丢弃详细信息控制器并从头开始查询库内容。