【问题标题】:Drawing in a background thread on iOS在 iOS 上的后台线程中绘图
【发布时间】:2011-10-09 07:19:27
【问题描述】:

我有一个带有一些非常复杂的绘图逻辑的视图(它是一个从 GIS 数据中绘制的地图视图)。在主线程上执行此绘图会锁定 UI 并使应用程序无响应。我想通过 NSOperation 将绘图移至后台线程。

构建这个的最佳方式是什么?

我目前正在绘制到内存外的 CGContext,然后将其转换为 CGImageRef,我将其发送到视图以在主线程上进行 blit。不幸的是,这会占用大量内存,并且似乎不再使用 GPU 加速,因为它的速度相当慢。有没有办法从后台线程直接绘制到视图?我知道 UIKit 不是多线程安全的,但也许有一些方法可以在我绘制时锁定视图?

【问题讨论】:

    标签: ios multithreading uikit core-graphics nsoperation


    【解决方案1】:

    iOS 4.0 之后,drawing is thread safe。您可能需要自己创建一个CGContext,但没有理由不能在后台线程上绘图。

    也就是说,大多数 UIKit 操作都不是。如果您需要这样做,您可以随时在后台线程中进行准备,然后在需要时使用performOnMainThread。甚至还有waitUntilDone。也就是说,显然你应该使用NSOperationNSOperationQueue

    【讨论】:

    【解决方案2】:

    我从来没有在 iPhone 上遇到过这种情况,但在 Mac 上我曾经遇到过类似的问题。

    1. 使用CGLayer 委派离线上下文的绘图活动。
    2. 尝试为当前的 NSRunLoop 添加计时器并在定时间隔执行您的图形命令。它应该看起来像这样......

    ...

    kRenderFPS 25.0 //This is Maximum value
    
    renderTimer = [[NSTimer timerWithTimeInterval:(1.0 / (NSTimeInterval)kRenderFPS) target:viewobject selector:@selector(RenderUI:) userInfo:nil repeats:YES] retain];
    
    
    [[NSRunLoop currentRunLoop] addTimer:renderTimer forMode:NSDefaultRunLoopMode];
    
    
    [[NSRunLoop currentRunLoop] addTimer:renderTimer forMode:NSModalPanelRunLoopMode];
    
    
    [[NSRunLoop currentRunLoop] addTimer:renderTimer forMode:NSEventTrackingRunLoopMode];
    
    //In view class
    -(void)RenderUI:(id)param
    {
        [self setNeedsDisplayInRect:[self bounds]];
    }
    

    这应该可以解决问题。

    还可以尝试对您的进程进行采样并检查谁在消耗 CPU。这将使 UI 响应迅速且非常快速。

    您提到的性能问题可能是由于其他原因。尝试 cpu 示例过程。它将让您深入了解谁实际占用了 CPU。

    【讨论】:

    • 所以我现在正在尝试这种方法,但即使我使用 NSTimer 运行并且只运行 50% 的时间(以 0.2 秒的间隔运行,每个绘图周期最多 0.1 秒),它似乎仍然忽略所有 UI 事件。这有什么诀窍吗?
    • 你尝试过哪种风格? CGLayer 或 NSRunLoop 或两者兼而有之?使用 CGLayer 委托离屏绘图,使用 NSRunloop 以定时间隔执行绘图命令。
    • 我注意到有人对我的回答投了反对票,但没有解释为什么 -1。它不酷。
    • 我同时使用了 CGLayer 和 NSRunLoop。现在我正在尝试使用 NSOperation 的 CGLayer(即在后台线程上)。不过,我在后台线程上的表现非常糟糕。 (虽然 UI 现在是响应式的。)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-23
    相关资源
    最近更新 更多