这个小项目的作用是在多个后台线程上加载媒体文件(图像或视频)的缩略图。一旦缩略图加载完成,您将在主线程上收到回调。代码使用系统 API,应该运行得非常快,尽管我没有任何关于性能的数据。我使用 UTIs 来检查媒体文件类型。我使用 dispatch_groups 以便您可以轻松等待多个加载任务,直到它们全部完成。您可以为并行运行多少个加载操作设置一个限制。(现在还没有提供方便的 API,如果需要,只需更改一个常量值即可。非常欢迎拉取请求。)代码似乎已经很好地同步,我也没有发现任何内存泄漏。有一个测试类和一些测试用例,以便于贡献。
要运行示例项目,首先克隆仓库,从 Example 目录运行 pod install
。测试项目名为 WDAsyncImageThumbnail_Example。查看测试类(WDAsyncImageThumbnailTest)以了解如何使用代码。需要 NSCache 实例。以下为概述。
NSCache *myCache = [[NSCache alloc]init];
NSURL *pic1URL = [myBundle URLForResource:@"testPics/0.JPG" withExtension:nil];
WDAsyncImageThumbnail *image = [WDAsyncImageThumbnail imageWithImageCache:myCache imageURL:pic1URL];
[im1 loadImageWithCallbackBlock:^(CGImageRef aImageRef, NSError *aError){
//handler here, e.g.
NSImage *im = [[NSImage alloc]initWithCGImage:aImageRef size:NSZeroSize];
}];
加载缩略图是一个昂贵的 I/O 操作,在某些情况下您可能希望在开始之前取消一个已计划的加载。(例如,当图像在一个网格中显示时,如果已经滚动并不再可见,则可能不需要该图像)。您可以使用 WDAsyncImageThumbnailDelegate 来实现这一点。请参阅提供的示例项目以获取更多详细信息。(实际上没有更多的细节 :) )
WDAsyncImageThumbnail *imageThumbnail = [WDAsyncImageThumbnail imageWithImageCache:cache imageURL:fileUrl];
imageThumbnail.delegate = self;
[imageThumbnail loadImageWithCallbackBlock:^(CGImageRef aImageRef, NSError *aError) {
self.image.image = [[NSImage alloc]initWithCGImage:aImageRef size:NSZeroSize];
}];
---------
#pragma mark - WDAsyncImageThumbnailDelegate
- (BOOL)imageWillLoad:(WDAsyncImageThumbnail *)aImage{
NSLog(@"Image will laod now. Return NO to stop the load and save your IO.");
return NO;
}
这类东西在 Objective-C 中迟早会造成头痛。所以我使用了 dispatch_groups。查看测试类以获取更多详细信息。简而言之
dispatch_group_t dispatchGroup = dispatch_group_create();
[WDAsyncImageThumbnail setDispatchGroup:dispatchGroup];
WDAsyncImageThumbnail *im1 = [WDAsyncImageThumbnail imageWithImageCache:imageCache imageURL:pic1URL];
WDAsyncImageThumbnail *im2 = [WDAsyncImageThumbnail imageWithImageCache:imageCache imageURL:pic2URL];
WDAsyncImageThumbnail *im3 = [WDAsyncImageThumbnail imageWithImageCache:imageCache imageURL:pic3URL];
[im1 loadImageWithCallbackBlock:^(CGImageRef aImageRef, NSError *aError) { /*your handler*/ }];
[im2 loadImageWithCallbackBlock:^(CGImageRef aImageRef, NSError *aError) { /*your handler*/ }];
[im3 loadImageWithCallbackBlock:^(CGImageRef aImageRef, NSError *aError) { /*your handler*/ }];
dispatch_group_notify(dispatchGroup, dispatch_get_main_queue(), ^{
NSLog(@"All tasks finished! This is called async after all images are loaded.");
});
或者如果您想同步等待.. (同样也查看测试类以获取更多详细信息)
//somewhere...
dispatch_group_t dispatchGroup = dispatch_group_create();
- (void)someMethod{
[WDAsyncImageThumbnail setDispatchGroup:dispatchGroup];
WDAsyncImageThumbnail *im1 = [WDAsyncImageThumbnail imageWithImageCache:imageCache imageURL:pic1URL];
WDAsyncImageThumbnail *im2 = [WDAsyncImageThumbnail imageWithImageCache:imageCache imageURL:pic2URL];
WDAsyncImageThumbnail *im3 = [WDAsyncImageThumbnail imageWithImageCache:imageCache imageURL:pic3URL];
[im1 loadImageWithCallbackBlock:^(CGImageRef aImageRef, NSError *aError) { /*your handler*/ }];
[im2 loadImageWithCallbackBlock:^(CGImageRef aImageRef, NSError *aError) { /*your handler*/ }];
[im3 loadImageWithCallbackBlock:^(CGImageRef aImageRef, NSError *aError) { /*your handler*/ }];
[self waitForGroup];
NSLog(@"When you see this text, all loads are already finished.");
}
----
- (void)waitForGroup{
__block BOOL didComplete = NO;
dispatch_group_notify(dispatchGroup, dispatch_get_main_queue(), ^{
didComplete = YES;
});
while( !didComplete ){
NSTimeInterval const interval = 0.002;
if( ![[NSRunLoop currentRunLoop]
runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:interval]] ){
[NSThread sleepForTimeInterval:interval];
}
}
}
WDAsyncImageThumbnail 通过 CocoaPods 提供。要安装它,只需将以下行添加到您的 Podfile 中
pod "WDAsyncImageThumbnail"
Fred, major.freddy {aaatttt} yahoo {doot} com
WDAsyncImageThumbnail 在MIT许可下可用。有关更多信息,请参阅LICENSE文件。