使用Grand Central Disatch从文件加载UIImage

我正在尝试使用gcd在后台加载图像。 我的第一次尝试没有奏效:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW,0), ^{ dispatch_async(dispatch_get_main_queue(), ^{ // create UI Image, add to subview }); }); 

注释掉后台队列代码,只留下主队列调度块不起作用:

 dispatch_async(dispatch_get_main_queue(), ^{ // create UI Image, add to subview }); 

在gcd块里面做ui的东西有一些窍门吗?

为了回应mattjgalloway的评论,我只是试图在后台线程中加载一个大的图像。 以下是我最初尝试的完整代码:

 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW,0), ^{ UIImage* img = [[UIImage alloc] initWithContentsOfFile: path]; dispatch_async(dispatch_get_main_queue(), ^{ imageView = [[[UIImageView alloc] initWithImage: img] autorelease]; imageView.contentMode = UIViewContentModeScaleAspectFill; CGRect photoFrame = self.frame; imageView.frame = photoFrame; [self addSubview:imageView]; }); }); 

我简化了它,以便我在主队列中运行所有内容,但是即使这样也不行。 我想,如果我不能让整个事情在主队列中工作,没有办法背景队列的东西将工作。


================ UPDATE ==============

我在一个全新的项目中尝试了上述技术(gcd和all),并且确实按预期工作。 只是不在我目前的项目。 所以我必须做一些缓慢而痛苦的淘汰工作来弄清楚什么是错的。 我正在使用这个背景加载在uiscrollview中显示图像。 发现图像的位有时会出现,但并不总是。 我会深究这个….

================ UPDATE ==============

看起来像这个问题是关于UIScrollView所有这一切都在里面。 我认为东西没有被吸引/刷新,当它应该

我运行你的代码。 它有一个例外。 你的意思是自我而不是自我?

情况1:

path是在属性中声明的。
imageView是在伊娃尔宣布

 - (IBAction)buttonImagePressed:(id)sender { self.path = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"picture1.jpg"]; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW,0), ^{ UIImage* img = [[UIImage alloc] initWithContentsOfFile: self.path]; dispatch_async(dispatch_get_main_queue(), ^{ imageView = [[[UIImageView alloc] initWithImage: img] autorelease]; imageView.contentMode = UIViewContentModeScaleAspectFill; CGRect photoFrame = self.view.frame; imageView.frame = photoFrame; [self.view addSubview:imageView]; }); }); } 

案例2:

path和imageView都是ivars。 – 没有财产被使用。

 - (IBAction)buttonImagePressed:(id)sender { // will crash if path is defined here // path = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"picture1.jpg"]; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW,0), ^{ //if path is defined here then it will work path = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"picture1.jpg"]; UIImage* img = [[UIImage alloc] initWithContentsOfFile:path]; dispatch_async(dispatch_get_main_queue(), ^{ imageView = [[[UIImageView alloc] initWithImage: img] autorelease]; imageView.contentMode = UIViewContentModeScaleAspectFill; CGRect photoFrame = self.view.frame; imageView.frame = photoFrame; [self.view addSubview:imageView]; }); }); } 

在案例2中,崩溃的地方,控制台中的消息说在apple.com上提交一个错误…

尝试在[self addSubview:imageView] setNeedDisplay [self addSubview:imageView]之后调用setNeedDisplay ,通过UIKit的大多数不是线程安全的方式,我不知道UIImage方法专门(也许在iOS4和更高),但我不会那。 如果要从后台加载图像,请使用线程安全的ImageIO或Core Graphics函数。
另一种方法是在后台线程上加载一个带有图像数据的NSData对象,然后在主线程上调用[UIImage alloc]inithWithData: data]

显示我的图像作为背景图像,而不是UIImageView添加为子视图的作品。 不知道为什么

 @interface PhotoView(){ UIImageView* imageView; } @end @implementation PhotoView -(id)initWithFrame:(CGRect)frame andPathToPhoto:(NSString*)path andSequenceView:(SequencerView*) sequencerView{ if(self = [super initWithFrame:frame]){ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW,0), ^{ UIImage* img = [[UIImage alloc] initWithContentsOfFile: path]; dispatch_async(dispatch_get_main_queue(), ^{ self.backgroundColor = [UIColor colorWithPatternImage:img]; }); [img release]; }); } return self; } @end