如何让ui始终保持响应并进行后台更新?

问题描述:

我正在创建一个每页显示8个缩略图的应用程序,它可以有n个页面。每个缩略图都是UIViews,并被添加到UIScrollView。不过,我已经使用Apple示例代码实现了Paging。如何让ui始终保持响应并进行后台更新?

的概率:

  1. 每个缩略图(UIView的)取150米 的毫秒被创建并添加到 滚动视图
  2. 因此,对于3页花费可怕 巨大时被创建并添加到 UI滚动查看。
  3. 此时滚动视图不是很respsonsive,这是非常生涩,并给出了不好的用户体验
  4. 如何创建缩略图并将其添加到的UIScrollView不影响触控反应?我希望它们独立于处理触摸事件的主线程运行(我想)。

另外我想提一下,当缩略图创建时,我会触发图像的异步下载,并且在下载完成时调用委托方法。

让我知道我有哪些选项可以提高响应速度并更新UI,而不会影响触摸操作。通过延迟加载缩略图网格,页面控件可以正常工作。

TIA,

普利文小号

+0

这是发生两次相同问题时发生的情况。人们开始投票,将两个问题都作为对方的重复问题来解决,他们都结束了。 – 2011-02-27 23:32:52

+0

嘿,这是我的互联网问题,因此我在我看到prev更新之前发布了两次问题。从今以后会很在乎。期待着一个好的解决方案。 :-) – 2011-02-28 05:36:13

Grand Central Dispatch很容易用于后台加载。但GCD仅适用于iOS4之后。如果您必须支持iOS3,那么performSelectorInBackground/performSelectorOnMainThread或NSOperationQueue会有帮助。

而且,请注意几乎UIKit类除了绘制到图形上下文外都不是线程安全的。例如,UIScrollView不是线程安全的,UIImage imageNamed:不是线程安全的,但是UIImage imageWithContentsOfFile:是线程安全的。

dispatch_queue_t mainQueue = dispatch_get_main_queue(); 
dispatch_queue_t concurrentQueue = 
    dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 

dispatch_async(concurrentQueue, ^{ 

    dispatch_apply([thumbnails count], concurrentQueue, ^(size_t index) { 

     Thumbnail *thumbnail = [thumbnails objectAtIndex:index]; 
     thumbnail.image = [UIImage imageWithContentsOfFile:thumbnail.url]; 

     dispatch_sync(mainQueue, ^{ 

      /* update UIScrollView using thumbnail. It is safe because this block is on main thread. */ 

     }); 
    } 

    /* dispatch_apply waits until all blocks are done */ 

    dispatch_async(mainQueue, ^{ 
     /* do for all done. */ 
    }); 
} 
+0

有关此操作的示例,请参阅[WWDC 2010会话视频](http://developer.apple.com/videos/wwdc/2010/)206“在iPhone中引入Blocks和Grand Central Dispatch ”。他们使用GCD演示了这种背景图像加载的演示。 – 2011-03-01 15:13:06

+0

我也为[NSURLConnection和Grand central dispatch]写了一个答案(http://*.com/questions/5037545/nsurlconnection-and-grand-central-dispatch/5151402#5151402)。这将有所帮助。 – 2011-03-01 20:28:59

我有类似的问题。
我所做的是在一个实例中,我只保留了3页内存并清除了所有内容。
如果假设有3个屏幕s1,s2,s3。用户正在查看s2。每当他滚动到s3时,我将删除s1并加载一个新页面s4。
这样用户会有更好的体验。并且会占用更少的内存。

+0

我并不担心内存,因为我也在内存中保留3页。然而,每个视图的元素需要很多时间才能创建,因此响应性很低。 – 2011-02-28 05:33:00

+0

然后唯一的方法是在图像加载时使用活动指示器。 ;) – SNR 2011-02-28 06:49:37

无论您使用的是子视图或每“页”或元素的滚动型的单独视图控制器,图像跳动或表现不佳可以通过改变代码的位置有所帮助。

专门为一个的PageControl滚动视图苹果样品码具有这样的事情:

[self loadScrollViewWithPage:page - 1]; 
[self loadScrollViewWithPage:page]; 
[self loadScrollViewWithPage:page + 1]; 

然而,代码出现在他们的方法“scrollViewDidScroll”样本。它试图通过同时滚动和加载来完成多个繁重的工作。即使你的图片是本地的,这也是令人讨厌的。

如果您将包含对当前页面的引用的此代码和相关代码移动到“scrollViewDidEndDecelerating”,则界面的急动被解决,因为加载发生在滚动视图不再移动时发生。