【问题标题】:Saving a thumbnail on a background thread在后台线程上保存缩略图
【发布时间】:2011-03-30 05:34:42
【问题描述】:

我正在尝试从 iPad 照片库中创建所选照片的​​缩略图 (288x288)。我在 UITableView 中显示了一组 ALAsset 对象,当我选择一行时,会显示该图像的较大预览 (288x288)。为了防止主线程阻塞,我试图在后台线程上创建缩略图,并将缩略图的副本缓存到文件系统。

在选中TableView行时,我在背景中调用loadPreviemage:

- (void)tableView:(UITableView *)tableView
        didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    // get the upload object from an array that contains a ALAsset object
    upload = [uploads objectAtIndex:[indexPath row]];

    [self performSelectorInBackground:@selector(loadPreviewImage:)
                           withObject:upload];

}

我传递了一个包含asseturl 属性的自定义上传对象:

- (void)loadPreviewImage:(MyUploadClass*)upload
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

    UIImage *preview = [upload previewImage];       
    [self performSelectorOnMainThread:@selector(setPreviewImage:)
                           withObject:preview
                        waitUntilDone:YES];

    [pool release];
}

这在主线程上调用以在加载后显示缩略图:

- (void)setPreviewImage:(UIImage*)image
{
    self.imageViewPreview.image = image;
    [self layoutSubviews];
}

这是 MyUploadClass 的一个方法:

- (UIImage *)previewImage
{
    __block UIImage *previewImage = [[UIImage imageWithContentsOfFile:
            [self uploadPreviewFilePath]] retain];

    if (previewImage == nil && asseturl)
    {
        ALAssetsLibrary* library = [[ALAssetsLibrary alloc] init];
        [library assetForURL:self.asseturl resultBlock:^(ALAsset *asset)
        {                         
            ALAssetRepresentation *rep = [asset defaultRepresentation]; 

            previewImage = [UIImage imageWithCGImage: [rep fullScreenImage]];
            previewImage = [[previewImage resizedImageWithContentMode:UIViewContentModeScaleAspectFit
                                             bounds:CGSizeMake(288, 288)
                               interpolationQuality:kCGInterpolationHigh] retain];

            NSData *previewData = UIImageJPEGRepresentation(previewImage, 1.0); 
            [previewData writeToFile:[self uploadPreviewFilePath] atomically:YES];   
         }
         failureBlock:^(NSError *error){ }];
         [library release];
    } 
    return [previewImage autorelease];
}

问题是我总是第一次得到 nil previewImage 并且只有在缩略图被缓存后我才得到一个图像对象。我究竟做错了什么?有没有更好的方法来解决这个问题?

【问题讨论】:

    标签: iphone multithreading alasset


    【解决方案1】:

    我没有清楚的理解 ALAssetsLibrary 的 resultBlock 是如何操作的,我的错误是认为执行是线性的。事实证明,在我的例子中,resultBlock 在主线程上执行,而 previewImage 中的其余代码在后台线程上执行。我得到 nil 是因为 previewImage 在 resultBlock 有机会结束其执行之前返回。我通过用以下方法替换 previewImage 解决了这个问题:

    - (void) loadPreviewImage:(CGSize)size withTarget:(id)target andCallback:(SEL)callback
    {
        NSString *path = [self uploadPreviewFilePath];    
        UIImage *previewImage = [UIImage imageWithContentsOfFile:path];  
    
        if (previewImage == nil && asseturl)
        {
            ALAssetsLibrary* library = [[ALAssetsLibrary alloc] init];
            [library assetForURL:self.asseturl resultBlock:^(ALAsset *asset)
            {
                if (asset) {                                  
                  ALAssetRepresentation *rep = [asset defaultRepresentation];   
    
                  UIImage *img = [UIImage imageWithCGImage: [rep fullScreenImage]];
    
                  img = [img resizedImageWithContentMode:UIViewContentModeScaleAspectFit
                        bounds:size interpolationQuality:kCGInterpolationHigh];
    
                  NSData *previewData = UIImageJPEGRepresentation(img, 1.0);                            
                  [previewData writeToFile:path atomically:YES];     
                  [target performSelectorOnMainThread:callback 
                                           withObject:img
                                        waitUntilDone:YES];
              }
           }
          failureBlock:^(NSError *error){ }];                        
          [library release];
      }
      else {
          [target performSelectorOnMainThread:callback withObject:img waitUntilDone:YES];
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-19
      • 1970-01-01
      • 1970-01-01
      • 2013-03-08
      • 2019-09-27
      • 1970-01-01
      • 1970-01-01
      • 2023-03-07
      相关资源
      最近更新 更多