有没有办法让 drawRect 立即工作? [英] Is there a way to make drawRect work right NOW?

查看:39
本文介绍了有没有办法让 drawRect 立即工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果您是 drawRect 的高级用户,您会知道当然 drawRect 在所有处理完成"之前不会真正运行.

If you are an advanced user of drawRect, you will know that of course drawRect will not actually run until "all processing is finished."

setNeedsDisplay 将视图标记为无效和操作系统,并且基本上等待所有处理完成.在您想要拥有的常见情况下,这可能会令人恼火:

setNeedsDisplay flags a view as invalidated and the OS, and basically waits until all processing is done. This can be infuriating in the common situation where you want to have:

  • 一个视图控制器 1
  • 启动一些功能 2
  • 其中递增 3
    • 创作出越来越复杂的艺术作品和 4
    • 在每一步,你都设置了NeedsDisplay(错误!)5

    当然,当您执行上述 1-6 步时,所发生的只是 drawRect 在第 6 步之后只运行一次.

    Of course, when you do the above 1-6, all that happens is that drawRect is run once only after step 6.

    您的目标是在第 5 点刷新视图.该怎么做?

    Your goal is for the view to be refreshed at point 5. What to do?

    推荐答案

    用户界面的更新发生在当前通过运行循环的末尾.这些更新都是在主线程上执行的,所以任何在主线程中运行时间长的(冗长的计算等)都会阻止界面更新的启动.此外,在主线程上运行一段时间的任何内容也会导致您的触摸处理无响应.

    Updates to the user interface happen at the end of the current pass through the run loop. These updates are performed on the main thread, so anything that runs for a long time in the main thread (lengthy calculations, etc.) will prevent the interface updates from being started. Additionally, anything that runs for a while on the main thread will also cause your touch handling to be unresponsive.

    这意味着没有办法强制"从主线程上运行的进程的其他点发生 UI 刷新. 前面的陈述并不完全正确,正如 Tom 的回答显示.您可以允许运行循环在主线程上执行的操作中间完成.但是,这仍然可能会降低您的应用程序的响应速度.

    This means that there is no way to "force" a UI refresh to occur from some other point in a process running on the main thread. The previous statement is not entirely correct, as Tom's answer shows. You can allow the run loop to come to completion in the middle of operations performed on the main thread. However, this still may reduce the responsiveness of your application.

    一般而言,建议您将需要一段时间执行的任何内容移至后台线程,以便用户界面可以保持响应.但是,您希望对 UI 执行的任何更新都需要在主线程上完成.

    In general, it is recommended that you move anything that takes a while to perform to a background thread so that the user interface can remain responsive. However, any updates you wish to perform to the UI need to be done back on the main thread.

    也许在 Snow Leopard 和 iOS 4.0+ 下最简单的方法是使用块,如下面的基本示例所示:

    Perhaps the easiest way to do this under Snow Leopard and iOS 4.0+ is to use blocks, like in the following rudimentary sample:

    dispatch_queue_t main_queue = dispatch_get_main_queue();
    dispatch_async(queue, ^{
        // Do some work
        dispatch_async(main_queue, ^{
            // Update the UI
        });
    });
    

    Do some work 上面的部分可能是一个冗长的计算,或者一个循环多个值的操作.在此示例中,UI 仅在操作结束时更新,但如果您希望在 UI 中持续跟踪进度,则可以将调度放置到需要执行 UI 更新的主队列.

    The Do some work part of the above could be a lengthy calculation, or an operation that loops over multiple values. In this example, the UI is only updated at the end of the operation, but if you wanted continuous progress tracking in your UI, you could place the dispatch to the main queue where ever you needed a UI update to be performed.

    对于较旧的操作系统版本,您可以手动或通过 NSOperation 中断后台线程.对于手动后台线程,您可以使用

    For older OS versions, you can break off a background thread manually or through an NSOperation. For manual background threading, you can use

    [NSThread detachNewThreadSelector:@selector(doWork) toTarget:self withObject:nil];
    

    [self performSelectorInBackground:@selector(doWork) withObject:nil];
    

    然后更新您可以使用的用户界面

    and then to update the UI you can use

    [self performSelectorOnMainThread:@selector(updateProgress) withObject:nil waitUntilDone:NO];
    

    请注意,我发现在处理连续进度条时需要使用前一个方法中的 NO 参数来获取持续的 UI 更新.

    Note that I've found the NO argument in the previous method to be needed to get constant UI updates while dealing with a continuous progress bar.

    这个示例应用程序我为我的班级创建的说明了如何使用NSOperations 和队列都用于执行后台工作,然后在完成后更新 UI.此外,我的 Molecules 应用程序使用后台线程来处理新结构,状态栏会随着进程的进行而更新.你可以下载源代码看看我是如何实现的.

    This sample application I created for my class illustrates how to use both NSOperations and queues for performing background work and then updating the UI when done. Also, my Molecules application uses background threads for processing new structures, with a status bar that is updated as this progresses. You can download the source code to see how I achieved this.

    这篇关于有没有办法让 drawRect 立即工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆