NSOperation mainQueue问题

时间:2012-06-22 14:32:41

标签: iphone ios uiimage nsoperation nsoperationqueue

我有幻灯片播放,我想要显示大图像,我添加到[NSOperation mainQueue]操作优先级较低,此操作显示图像。

如果图像很小,一切正常,但是当图像大约5Mb时,视图会冻结1秒钟,我无法滚动幻灯片。我认为,显示iPhone的大图像非常困难,主队列太过分了。

但我不理解它,因为我的所有显示代码都是以低优先级操作执行的。

这是显示代码。

[imageView removeFromSuperview];
imageView = nil;

// reset our zoomScale to 1.0 before doing any further calculations
self.zoomScale = 1.0;

// make a new UIImageView for the new image
self.imageView = [[[UIImageView alloc] initWithImage:image] autorelease];
[self addSubview:imageView];

self.contentSize = [image size];
[self setMaxMinZoomScalesForCurrentBounds];
self.zoomScale = self.minimumZoomScale;

可能我可以设置手势识别器的优先级(UIScrollView的常规任务识别器吗?)

更新

请查看我的新主题,我更恰当地描述了问题my topik

2 个答案:

答案 0 :(得分:3)

优先级与调度有关。如果在runloop迭代期间排队一堆操作,那么它们将由它们在该队列上的优先级执行。

加快这一速度的一个解决方案是要么包含缩放到您显示它们的确切大小的资源。如果您尝试在200x200区域中显示2000x2000 px图像,那么系统可以扩展所有这些记忆中的东西。您还可以以编程方式动态创建较小的图像以适合图像。这可以在后台队列上完成,因此您的UI仍然可以响应。

How to resize the image programmatically in objective-c in iphone

答案 1 :(得分:0)

如果我理解你的身份并且你做了类似

的事情
NSOperationQueue* queue = [NSOperationQueue mainQueue];

然后,您添加到它的任何NSOperation将在并发的主调度队列上执行(并负责在主线程上执行任务)。这可以解释冻结。您可以创建自己的队列,为每个NSOperation启动一个线程,并释放主线程以正常呈现UI:

NSOperationQueue* queue = [[NSOperationQueue alloc] init];
[queue addOperation:operation];

然而,这会引起问题。当图像加载完毕并将其传递给屏幕上的UIImageView时,在实际呈现图像之前会有很大的延迟,因为主(UI)线程在选择刷新之前不会知道该动作(一些几秒钟后)。对此的解决方案是在NSOperation的main方法的末尾添加'performInMainThread'消息:

-(void)main {
    NSData *bgImageData = [NSData dataWithContentsOfURL:self.targetUrl];
    UIImage *img = [UIImage imageWithData:bgImageData];
    [self performSelectorOnMainThread:@selector(insertImageLoaded:)
                           withObject:img
                        waitUntilDone:YES];
}

'insertImageLoaded'在NSOperation中,并且会将setImage:(UIImage *)img调用到你想要的组件。