我正在尝试从iPad照片库中创建所选照片的缩略图(288x288)。我在UITableView中显示了一组ALAsset对象,当我选择一行时,会显示该图像的更大预览(288x288)。为了防止主线程阻塞,我正在尝试在后台线程上创建缩略图,并将缩略图的副本缓存到文件系统。
在视图控制器中选择tableview行时,我在后台调用loadPreviewImage:
- (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,只有在缓存缩放后我得到一个图像对象。我究竟做错了什么?有没有更好的方法解决这个问题?
答案 0 :(得分:-1)
我没有清楚地理解ALAssetsLibrary的resultBlock如何运作,我的错误是认为执行是线性的。事实证明,在我的情况下,resultBlock在主线程上执行,而previewImage中的其余代码在后台线程上执行。因为在resultBlock有机会结束执行之前返回了previewImage,所以我得到了nil。我通过使用以下方法替换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];
}
}