【问题标题】:How to make ui responsive all the time and do background updating?如何让 ui 始终响应并进行后台更新?
【发布时间】:2011-02-27 14:28:12
【问题描述】:

我正在创建一个应用程序,它每页显示 8 个缩略图,它可以有 n 个页面。这些缩略图中的每一个都是 UIView 并被添加到 UIScrollView。但是我已经使用 Apple 示例代码实现了分页。

问题:

  1. 每个缩略图(UIView)占用 150 要创建并添加到的毫秒数 滚动视图
  2. 因此对于 3 页它需要很糟糕 创建和添加大量时间 UI 滚动视图。
  3. 此时,滚动视图的响应速度不是很快,而且非常生涩,用户体验很差
  4. 如何创建缩略图并将它们添加到 UIScrollview 而不影响触摸响应?我希望它们独立于负责处理触摸事件的主线程运行(我想)。

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

让我知道在不影响触摸操作的情况下,我必须使用哪些选项来提高响应速度并更新 UI。页面控件适用于延迟加载缩略图网格。

TIA,

普雷文斯

【问题讨论】:

  • 当您两次发布相同的问题时会发生这种情况。人们开始投票结束这两个问题,因为它们彼此重复,最终都被关闭了。
  • 嘿,这是我的互联网问题,因此我在看到上一个更新之前两次发布了这个问题。以后会小心的。期待一个好的解决方案。 :-)

标签: iphone objective-c cocoa asynchronous


【解决方案1】:

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. */
    });
}

【讨论】:

【解决方案2】:

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

【讨论】:

  • 我不担心内存,因为我还在内存中保留了 3 页。然而,每个视图的元素都需要大量时间来创建,因此响应速度很慢。
  • 那么唯一的方法是在图像加载时使用活动指示器。 ;)
【解决方案3】:

无论您是为 Scrollview 的每个“页面”或元素使用子视图还是单独的 ViewController,都可以通过更改代码的位置来解决抖动或性能不佳的问题。

具体来说,带有 pagecontrol 的滚动视图的苹果示例代码是这样的:

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

但是,该代码出现在他们的示例中的方法“scrollViewDidScroll”中。它试图通过同时滚动和加载来完成多项繁重的工作。即使你的图片是本地的,这也很糟糕。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-02-04
    • 1970-01-01
    • 1970-01-01
    • 2016-04-07
    • 2017-05-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多