Usar NSOperation es curiosamente lento

Estoy lidiando con un problema aquí. Hay una vista que utilizo para ver las miniaturas de un documento en mi aplicación. Desde que se cargaron las miniaturas se networkingujo el hilo principal, busqué soluciones alternativas y terminé haciendo una operación NSOperation para la creación de miniaturas.

Estoy mostrando una vista con frameworks de miniatura vacíos y el indicador de actividad correspondiente para decirle al usuario "espera, están en path". Pero esto lleva tanto time que estoy pensando en poner algo de música para que la espera sea más agradable x_X.

Tengo este NSOperationQueue configurado con 10 operaciones concurrentes máximas. El ajuste ayudó un poco con la parte de carga, pero solo un poco. Cargando un solo pulgar todavía toma como 6 segundos y eso y lo extraño es que cargar 10 toma lo mismo. El siguiente código es la operación misma

@class ThumbnailView; @protocol LoadThumbnailOperationDelegate; @interface LoadThumbnailOperation : NSOperation { NSString *key; id<LoadThumbnailOperationDelegate> delegate; @private CGSize _size; CGPDFDocumentRef _docRef; UIImage * _image; NSInteger _page; } @property (nonatomic,retain) NSString * key; @property (nonatomic,assign) id<LoadThumbnailOperationDelegate>delegate; -(id)initWithPage:(NSInteger)page operationKey:(NSString *)opKey fromDocRef:(CGPDFDocumentRef)docRef size:(CGSize)size delegate:(id<LoadThumbnailOperationDelegate>)aDelegate; -(NSInteger)getPage ; @protocol LoadThumbnailOperationDelegate <NSObject> -(void)operation:(LoadThumbnailOperation*)operation finishedLoadingThumbnail:(UIImage*)image; @end @interface LoadThumbnailOperation (private) -(UIImage*)makeThumbnailForPage:(NSInteger)page; @end @implementation LoadThumbnailOperation @synthesize key; @synthesize delegate; -(id)initWithPage:(NSInteger)page operationKey:(NSString *)opKey fromDocRef:(CGPDFDocumentRef)docRef size:(CGSize)size delegate:(id<LoadThumbnailOperationDelegate>)aDelegate{ self = [super init]; if (self) { self.key = opKey; _docRef = docRef; CGPDFDocumentRetain(_docRef); _size = size; _page = page; self.delegate = delegate; } return self; } -(void)main { #if DEBUG NSLog( @"LoadThumbnailOperaiton.m -> main key:%@",key); #endif NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init]; if (![self isCancelled]) { _image = [self makeThumbnailForPage:_page]; [_image retain]; } if(![self isCancelled]){ if ([delegate respondsToSelector:@selector(operation:finishedLoadingThumbnail:)]) { [delegate operation:self finishedLoadingThumbnail:_image]; } } [pool release]; } -(void)dealloc { [key release]; CGPDFDocumentRelease(_docRef); [_image release]; [super dealloc]; } #pragma mark - #pragma mark graphics -(UIImage*) makeThumbnailForPage :(NSInteger) page { #if DEBUG NSLog( @"LoadThumbnailOperaiton.m -> makeThumbnailForPage:%d",page); #endif CGPDFPageRef pdfPage = CGPDFDocumentGetPage(_docRef, page); if (pdfPage !=NULL){ CGPDFPageRetain(pdfPage); }else { NSAssert (pdfPage==NULL,@"pdf page NULL"); } CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGContextRef context = CGBitmapContextCreate(NULL, _size.width, _size.height, 8, /* bits per component*/ _size.width * 4, /* bytes per row */ colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); CGColorSpaceRelease(colorSpace); CGContextClipToRect(context, CGRectMake(0, 0, _size.width,_size.height)); CGRect pdfPageRect = CGPDFPageGetBoxRect(pdfPage, kCGPDFMediaBox); CGRect contextRect = CGContextGetClipBoundingBox(context); CGAffineTransform transform =aspectFit(pdfPageRect, contextRect); CGContextConcatCTM(context, transform); CGContextDrawPDFPage(context, pdfPage); /* create bitmap context */ CGImageRef image = CGBitmapContextCreateImage(context); CGContextRelease(context); UIImage *uiImage = [[UIImage alloc]initWithCGImage:image]; // clean up [uiImage autorelease]; CGImageRelease(image); CGPDFPageRelease(pdfPage); return uiImage; } -(NSInteger)getPage { return _page; } @end 

Este es el método de delegado en el controller de vista que agrega las imágenes que se han cargado

NOTA: esta aplicación es solo para iPad.

Gracias de antemano por su ayuda

Bien, encontré una solución a este problema. Lo solucioné comprobando si la llamada de delegado se realizó en el hilo principal o no. Aparentemente, las operaciones se realizaron bastante rápido, pero la llamada del delegado no fue porque no se realizó en el hilo principal. Por lo tanto, asegúrese de hacer su llamada de delegado en ese hilo utilizando el método – [NSObject performSelectorOnMainThread:].

Esto aún puede no ser rápido para algunos clientes. Terminé generando miniaturas de PDF con el automatizador y agregándolos al package de aplicaciones y cargándolos del disco en su lugar. Es mucho más rápido que generarlos en el ipad.

NOTA: esta aplicación es solo para iPad.

El iPad tiene un núcleo.

No solo la puesta en marcha de la concurrency hasta 11 no hará las cosas más rápido, en realidad la hará considerablemente más lenta debido a la contención del autobús, las limitaciones de E / S y las fallas de caching.

Lo único que impide que su aplicación se ejecute más lentamente es NSOperation; automáticamente acelera la concurrency para evitar exactamente los problemas que menciono de un desempeño degradante mucho peor de lo que actualmente estás viendo.