I've a NSOperation class that generated small and large image from a PHASSET. It's something like this:
#import "MultipleImageOperation.h"
@implementation MultipleImageOperation
@synthesize asset = _asset;
@synthesize tag = _tag;
@synthesize isLogo = _isLogo;
@synthesize delegate = _delegate;
-(id)initWithAsset:(PHAsset*) asset andTag:(NSUInteger)theTag andDelegate:(id<MultipleImageOperationDelegate>)theDelegate {
if(self = [super init]) {
_asset = asset;
_tag = theTag;
_delegate = theDelegate;
}
return self;
}
- (void)main {
@autoreleasepool {
__block UIImage *smallImage, *largeImage;
if (self.isCancelled == NO){
PHImageRequestOptions *requestOptions = [[PHImageRequestOptions alloc] init];
requestOptions.resizeMode = PHImageRequestOptionsResizeModeExact;
requestOptions.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;
requestOptions.synchronous = true;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
PHImageManager *manager = [PHImageManager defaultManager];
[manager requestImageForAsset:_asset
targetSize:!_isLogo? LARGE_IMAGE_SIZE : COMPANY_LOGO_LARGE_SIZE
contentMode:PHImageContentModeAspectFit
options:requestOptions
resultHandler:^void(UIImage *image, NSDictionary *info) {
NSData *imageData = UIImagePNGRepresentation(image);
NSString *filename = [NSString stringWithFormat:@"/img_%f.png", [[Utils getCurrentDate] timeIntervalSince1970]];
NSString *tempPath = [documentsDirectory stringByAppendingString:filename];
[imageData writeToFile:tempPath atomically:YES];
largeImage = image;
}];
[manager requestImageForAsset:_asset
targetSize:!_isLogo? SMALL_IMAGE_SIZE : COMPANY_LOGO_SMALL_SIZE
contentMode:PHImageContentModeAspectFit
options:requestOptions
resultHandler:^void(UIImage *image, NSDictionary *info) {
smallImage = image;
}];
if ([self.delegate respondsToSelector:@selector(multipleImageProcessingOperationCompletedForTag:withSmallImage:andLargeImage:)]) {
[self.delegate multipleImageProcessingOperationCompletedForTag:_tag withSmallImage:smallImage andLargeImage:largeImage];
}
}
}
}
@end
Delegate method is as follow:
- (void) multipleImageProcessingOperationCompletedForTag:(NSUInteger)tag withSmallImage:(UIImage *)smallImage andLargeImage:(UIImage*)largeImage {
Media *tempMedia;
tempMedia = [self.imagesList objectAtIndex:tag];
tempMedia.smallImage = smallImage;
tempMedia.mediaContent = largeImage;
tempMedia.mediaContentSize = [NSNumber numberWithDouble:([Utils convertToNSDataFromUIImage:largeImage].length/BYTES_IN_GB)];
[self updateImagesList:tempMedia];
photoOperations--;
if ( photoOperations == 0 ) {
if ([self.delegate respondsToSelector:@selector(updateDisplay)]) {
dispatch_async(dispatch_get_main_queue(), ^{
[self.delegate updateDisplay];
});
}
}
}
018-11-05 16:20:09.633[722:137251] *** -[UIImage retain]: message sent to deallocated instance 0x198dbe20
small image is always nil! I am stuck with this!
I don't know anything about your image generation libraries, but it looks like the method that you use to create the small image with is asynchronous. That means that when you are calling your delegate method the small image method has likely not finished it's task. I would do:
[manager requestImageForAsset:_asset
targetSize:!_isLogo? SMALL_IMAGE_SIZE : COMPANY_LOGO_SMALL_SIZE
contentMode:PHImageContentModeAspectFit
options:requestOptions
resultHandler:^void(UIImage *image, NSDictionary *info) {
smallImage = image;
if ([self.delegate respondsToSelector:@selector(multipleImageProcessingOperationCompletedForTag:withSmallImage:andLargeImage:)])
{
[self.delegate multipleImageProcessingOperationCompletedForTag:_tag withSmallImage:smallImage andLargeImage:largeImage];
}
}];
But you are also going to have to make sure the large image method is done as well (in case it is asynchronous as well).