iphone-GCD应用

//网络资源
// from: http://blog.csdn.net/favormm/article/details/6453260

//***************************************************************************//
//功能
1. 预定义了大量的要下载的图片URL
2. 创建一个GCD queue并开始下载图片
3. 在动画出现消失的时候,同时显示图片

//代码

@interface UIImageView (DispatchLoad)
- (void) setImageFromUrl:(NSString*)urlString;
- (void) setImageFromUrl:(NSString*)urlString
completion:(void (^)(void))completion;
@end



#import "UIImageView+DispatchLoad.h"
@implementation UIImageView (DispatchLoad)
- (void) setImageFromUrl:(NSString*)urlString {
[self setImageFromUrl:urlString completion:NULL];
}
- (void) setImageFromUrl:(NSString*)urlString
completion:(void (^)(void))completion {

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

NSLog(@"Starting: %@", urlString);
UIImage *avatarImage = nil;
NSURL *url = [NSURL URLWithString:urlString];
NSData *responseData = [NSData dataWithContentsOfURL:url];
avatarImage = [UIImage imageWithData:responseData];
NSLog(@"Finishing: %@", urlString);

if (avatarImage) {
dispatch_async(dispatch_get_main_queue(), ^{
self.image = avatarImage;
});
dispatch_async(dispatch_get_main_queue(), completion);
}
else {
NSLog(@"-- impossible download: %@", urlString);
}
});
}
@end



//************************************************************************//

坦福大学关于gcd的代码,这段代码逐步演示了如何修正错误,其中用到的既是串行队列

1。这个是原始代码
view plain

- (void)viewWillAppear:(BOOL)animated
{
NSData *imageData = [FlickrFetcher imageDataForPhotoWithURLString:photo.URL];
UIImage *image = [UIImage imageWithData:imageData];
self.imageView.image = image;
self.imageView.frame = CGRectMake(0, 0, image.size.width, image.size.height);
self.scrollView.contentSize = image.size;
}


2。这个是采用gcdd的代码,里面有错误3处
view plain

- (void)viewWillAppear:(BOOL)animated
{
dispatch_queue_t downloadQueue = dispatch_queue_create(“Flickr downloader”, NULL);
dispatch_async(downloadQueue, ^{
NSData *imageData = [FlickrFetcher imageDataForPhotoWithURLString:photo.URL];
UIImage *image = [UIImage imageWithData:imageData];
self.imageView.image = image;
self.imageView.frame = CGRectMake(0, 0, image.size.width, image.size.height);
self.scrollView.contentSize = image.size;
});
}


3。第一个错误,UI更新只能在主线程中 Problem! UIKit calls can only happen in the main thread!
改正后如下:
view plain

- (void)viewWillAppear:(BOOL)animated
{
dispatch_queue_t downloadQueue = dispatch_queue_create(“Flickr downloader”, NULL);
dispatch_async(downloadQueue, ^{
NSData *imageData = [FlickrFetcher imageDataForPhotoWithURLString:photo.URL];
dispatch_async(dispatch_get_main_queue(), ^{
UIImage *image = [UIImage imageWithData:imageData];
self.imageView.image = image;
self.imageView.frame = CGRectMake(0, 0, image.size.width, image.size.height);
self.scrollView.contentSize = image.size;
});
});
}


4。第二个错误,NSManagedObjectContext并不是线程安全的,gcd中访问成员变量有危险
Problem! NSManagedObjectContext is not thread safe,
so we can’t call photo.URL in downloadQueue’s t
改正后如下:
view plain

- (void)viewWillAppear:(BOOL)animated
{
NSString *url = photo.URL;
dispatch_queue_t downloadQueue = dispatch_queue_create(“Flickr downloader”, NULL);
dispatch_async(downloadQueue, ^{
NSData *imageData = [FlickrFetcher imageDataForPhotoWithURLString:url];
dispatch_async(dispatch_get_main_queue(), ^{
UIImage *image = [UIImage imageWithData:imageData];
self.imageView.image = image;
self.imageView.frame = CGRectMake(0, 0, image.size.width, image.size.height);
self.scrollView.contentSize = image.size;
});
});
}


5。第三个错误,队列创建后没有释放,内存泄露
view plain

- (void)viewWillAppear:(BOOL)animated
{
NSString *url = photo.URL;
dispatch_queue_t downloadQueue = dispatch_queue_create(“Flickr downloader”, NULL);
dispatch_async(downloadQueue, ^{
NSData *imageData = [FlickrFetcher imageDataForPhotoWithURLString:url];
dispatch_async(dispatch_get_main_queue(), ^{
UIImage *image = [UIImage imageWithData:imageData];
self.imageView.image = image;
self.imageView.frame = CGRectMake(0, 0, image.size.width, image.size.height);
self.scrollView.contentSize = image.size;
});
});
dispatch_release(downloadQueue); //won’t actually go away until queue is empty
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值