Parte de mi aplicación tiene un navegador de fotos, algo similar a la aplicación de fotos de Apple, con un controlador de vista inicial para buscar miniaturas de fotos y una vista detallada que se muestra al tocar una foto.ALAssetsLibrary - bloqueo después de recibir ALAssetsLibraryChangedNotification
Estoy usando ALAssetsLibrary para acceder a las fotos, y paso una serie de URL ALAsset a mi controlador de vista detallada para que pueda pasar de una foto a la siguiente.
Todo funciona muy bien, hasta que reciba una ALAssetsLibraryChangedNotification durante el escaneo de una fotografía a otra (en el controlador de la vista de detalle), que a menudo resulta en un accidente:
NOTIFICACIÓN: la biblioteca de activos cambió mi // NSLog propia para cuando se produce la notificación
activos de carga ... // mi propia NSLog para cuando empiece a recargar activos en el navegador de miniaturas
aserción: (tamaño == BytesRead), la función - [ALAssetRepresentation _imageData], presentar /SourceCache/AssetsLibrary/MobileSlideShow-1373.58.1/Sources/ALAssetRepresentation.m, línea 224.
La línea de código específica de que se estrelle en adelante, es en llamando [metadatos currentRep] como se muestra aquí:
- (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");
}
}
entiendo que una vez que se recibe una notificación, que invalida cualquier referencia a objetos ALAsset y ALAssetRepresentation ... pero ¿cómo se supone que voy a hacer frente a la situación en la que invalida algo justo en el medio de intentar acceder?
He tratado de establecer un BOOL, justo cuando se recibe la notificación de abortar por completo y bloquear [currentRep metadatos] que alguna vez se llamó, pero incluso eso no coge cada vez:
if (self.receivedLibraryChangeNotification) {
NSLog(@"received library change notification, need to abort");
}
else {
metaDictionary = [currentRep metadata];
}
Es hay algo que pueda hacer? En este punto, estoy casi listo para abandonar el uso del marco ALAssetsLibrary.
(nota de este hilo sin resolver en los foros dev de Apple que describen el mismo problema: https://devforums.apple.com/message/604430)
Tengo que hacer más pruebas ... pero eso puede haber ayudado. No se muestra en mi código anterior (ya que quería simplificarlo para publicar aquí), pero se estaba llamando a [metadatos currentRep] en una cadena de fondo. Lo cambié para recuperar el diccionario de metadatos dentro del resultado resultFlock "assetForURL" como sugeriste, que está en el hilo principal. Hasta ahora no se ha bloqueado ... ¿quizás el método de metadatos de ALAssetRepresentation no es seguro para subprocesos? –
Lo más importante aquí es que lleva tiempo obtener medios con 'assetForURL'. Por lo tanto, fuera del bloque de finalización no puede estar seguro de que haya descargado los medios ... – voromax
Actualicé mi pregunta para mostrar con precisión cómo estaba llamando al método de "metadatos" en un hilo de fondo. En función de su respuesta, la cambié para que recuperara primero el diccionario de metadatos y luego pasara eso y el activo a mi método configureDetailView. De nuevo, necesito hacer más pruebas, pero hasta ahora todo bien ... –