我需要將圖像從NSDocumentDirectory讀取到多個uiimageview異步,因此它不會阻止用戶界面。 我知道我可以在後臺使用執行選擇器來加載一個uiimage,但是我怎樣才能將它與動態uiimageview相關聯?來自異步文檔的圖像
2
A
回答
4
一個方便的方法是使用塊,這樣的:
[self loadFullImageAt:imagePath completion:^(UIIMage * image){
self.imageView.image = image;
}];
你想要在加載圖像數據(因爲UIImage
否則加載圖像數據的延遲 - 當你第一次訪問它)。在仍然處於後臺線程中的情況下解壓縮圖像也是一個好主意,所以當我們第一次使用圖像時,主線程不需要這樣做。
- (void)loadFullImageAt:(NSString *)imageFilePath completion:(MBLoaderCompletion)completion {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
NSData *imageData = [NSData dataWithContentsOfFile:imageFilePath];
UIImage *image = nil;
if (imageData) {
image = [[[UIImage alloc] initWithData:imageData] decodedImage];
}
dispatch_async(dispatch_get_main_queue(), ^{
completion(image);
});
});
}
回調被定義爲:
typedef void (^MBLoaderCompletion)(UIImage *image);
下面是一個UIImage
類別實現該解壓縮的代碼:
的UIImage + Decode.h
#import <UIKit/UIKit.h>
@interface UIImage (Decode)
- (UIImage *)decodedImage;
@end
的UIImage +十二月ode.m
#import "UIImage+Decode.h"
@implementation UIImage (Decode)
- (UIImage *)decodedImage {
CGImageRef imageRef = self.CGImage;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(NULL,
CGImageGetWidth(imageRef),
CGImageGetHeight(imageRef),
8,
// Just always return width * 4 will be enough
CGImageGetWidth(imageRef) * 4,
// System only supports RGB, set explicitly
colorSpace,
// Makes system don't need to do extra conversion when displayed.
kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little);
CGColorSpaceRelease(colorSpace);
if (!context) return nil;
CGRect rect = (CGRect){CGPointZero,{CGImageGetWidth(imageRef), CGImageGetHeight(imageRef)}};
CGContextDrawImage(context, rect, imageRef);
CGImageRef decompressedImageRef = CGBitmapContextCreateImage(context);
CGContextRelease(context);
UIImage *decompressedImage = [[UIImage alloc] initWithCGImage:decompressedImageRef scale:self.scale orientation:self.imageOrientation];
CGImageRelease(decompressedImageRef);
return decompressedImage;
}
@end
此處提供的樣本代碼假設我們使用ARC。
1
你可以使用NSThread/dispatch隊列來創建線程,這些線程可以創建你的UIImageView -s並在其中加載圖像。
2
當你說「動態」的UIImageView,這些在UIScrollView上以編程方式創建?在UITableView? samfisher在基本問題上是完全正確的,但是細節有所不同,這取決於你創建UIImageView的方式(例如,如果UITableView,你需要確保單元格仍然可見並且沒有出列;如果是UIScrollView,如果圖像在屏幕上仍然可見(尤其是如果圖像很大或很多)),則可能只想加載UIImageView。
但基本的想法是,你可以這樣做:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
UIImage *image = [self getTheImage];
// ok, now that you have the image, dispatch the update of the UI back to the main queue
dispatch_async(dispatch_get_main_queue(), ^{
// if the image view is still visible, update it
});
});
請注意,您調用的一些背景隊列或線圖像的檢索,但要確保更新UI回主線!
如果您要更新滾動視圖,則可能需要檢查視圖是否仍然可見,如預計的here或here。如果你正在更新一個tableview,可能像this這樣的東西檢查單元格是否仍然可見。這一切都取決於你想要做什麼。
相關問題
- 1. 異步圖像 - 僅用於顯示來自網頁的圖像?
- 2. 來自PDF文檔的快照圖像
- 3. 異步下載和緩存來自url的圖像
- 4. 異步和文檔準備
- 5. 異步加載的圖像
- 6. 如何在滾動視圖中異步顯示來自url的圖像?
- 7. 異步閱讀從Tesseract圖像文本?
- 8. 從文件異步加載圖像
- 9. 異步加載圖像
- 10. 異步添加圖像 - ASIHTTPRequest
- 11. 獲取圖像異步
- 12. 異步圖像下載表
- 13. 加載圖像異步
- 14. iOS - 異步圖像下載
- 15. 異步圖像下載
- 16. 異步圖像加載
- 17. 異步圖像加載
- 18. 異步保存圖像
- 19. 異步處理圖像(Django)
- 20. 用異步更新圖像
- 21. 異步GET圖像CollectionView
- 22. 圖像控制異步
- 23. 異步圖像下載器
- 24. 異步圖像可可
- 25. 如何從異步任務中的URL txt文檔加載圖像?
- 26. 如何在Android中異步顯示來自服務器的圖像?
- 27. 來自Python 3的TypeError異步循環
- 28. 來自webapp的異步調用
- 29. 來自.Net的異步電子郵件
- 30. 來自flex的多個異步調用
真棒回答。謝謝! –
這是一個很好的答案。我們可以修改它以添加取消機制 –