В части моего приложения есть браузер фотографий, чем-то похожий на приложение Apple Photos, с начальным контроллером просмотра для просмотра миниатюр фотографий и подробным представлением, которое отображается при нажатии на фотографию.
Я использую ALAssetsLibrary для доступа к фотографиям и передаю массив URL-адресов ALAsset своему контроллеру подробного представления, чтобы вы могли переходить от одной фотографии к другой.
Все работает отлично, пока я не получаю уведомление ALAssetsLibraryChangedNotification при переходе от одной фотографии к другой (в контроллере подробного представления), что часто приводит к сбою:
УВЕДОМЛЕНИЕ: библиотека ресурсов изменена // на мой собственный NSLog при появлении уведомления
загрузка ресурсов... // мой собственный NSLog, когда я начинаю перезагружать ресурсы в браузере эскизов
Ошибка утверждения: (размер == bytesRead), функция -[ALAssetRepresentation _imageData], файл /SourceCache/AssetsLibrary/MobileSlideShow-1373.58.1/Sources/ALAssetRepresentation.m, строка 224.
Конкретная строка кода, на которой происходит сбой, находится в вызове [метаданные currentRep], как показано здесь:
- (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, описывающую ту же проблему: https://devforums.apple.com/message/604430 )