【问题标题】:App crashing after while calling delegate调用委托后应用程序崩溃
【发布时间】:2018-11-05 13:24:14
【问题描述】:

我有一个 NSOperation 类,它可以从 PHASSET 生成大小图像。是这样的:

#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

委托方式如下:

- (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 保留]: 发送到已释放实例 0x198dbe20 的消息

小图像总是零!我被这个困住了!

【问题讨论】:

  • 你需要在你的逻辑中的某个地方保存一个图像的引用,它只是在自动释放池被弹出时被释放。

标签: ios delegates uiimage nsoperationqueue nsoperation


【解决方案1】:

我对您的图像生成库一无所知,但看起来您用于创建小图像的方法是异步的。这意味着当您调用委托方法时,小图像方法可能还没有完成它的任务。我会这样做:

[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];
        }
}];

但您还必须确保大图像方法也已完成(以防它也是异步的)。

【讨论】:

    猜你喜欢
    • 2011-02-13
    • 2017-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-16
    相关资源
    最近更新 更多