我的应用程序的一部分有一个照片浏览器,有点类似于苹果的照片应用程序,有一个初始视图控制器来浏览照片缩略图和一个详细视图,当您点击照片时显示它。
我使用ALAssetsLibrary访问照片,并向我的详细视图控制器传递ALAsset URL数组,以便您可以从一个照片滑动到另一个照片。
一切都很好,直到我在滑动照片时(在详细视图控制器中),收到了ALAssetsLibraryChangedNotification,这经常导致崩溃:
NOTIFICATION: the asset library changed // 我自己的NSLog,用于当通知发生时
loading assets... // 我自己的NSLog,用于当我开始在缩略图浏览器中重新加载资源时
Assertion failed: (size == bytesRead), function - [ALAssetRepresentation _imageData],file / SourceCache / AssetsLibrary / MobileSlideShow-1373.58.1 / Sources / ALAssetRepresentation.m, line 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 metadata],但即使如此,有时仍然无法捕获它:
if (self.receivedLibraryChangeNotification) {
NSLog(@"received library change notification, need to abort");
}
else {
metaDictionary = [currentRep metadata];
}
有什么我可以做的吗?这时我几乎要放弃使用ALAssetsLibrary框架了。
(请注意,苹果开发者论坛上还有一个未解决的线程描述了同样的问题:https://devforums.apple.com/message/604430)
assetForURL
获取媒体需要时间。因此,在完成块之外,您不能确定是否已下载媒体... - voromax