管理iOS上的CPU密集型线程[英] Managing CPU intensive threads on iOS

本文是小编为大家收集整理的关于管理iOS上的CPU密集型线程的处理方法,想解了管理iOS上的CPU密集型线程的问题怎么解决?管理iOS上的CPU密集型线程问题的解决办法?那么可以参考本文帮助大家快速定位并解决问题。

问题描述

我是一位经验丰富的 C/C++ 程序员,正在快速了解 iPhone 上的 Objective C.我进行了很多搜索,但对于必须是常见问题的问题没有找到满意的答案;如果这在其他地方得到回答,我深表歉意,将不胜感激.

我的应用程序占用大量 CPU.UI 有一个简单的显示屏,显示进度和一个开始/停止按钮.分配尽可能多的 CPU 周期以完成工作的最佳方法是什么,同时仍确保定期更新显示并且启动/停止按钮响应?我读过你不应该在主线程中工作,但除此之外我没有找到很多建议.鉴于此,我在 NSOperation 队列中实现了我的工作.我还将屏幕刷新放在了自己的队列中.我还用 NSThread sleepForTimeIntervals 随意地洒了代码.我已经尝试过从 .001 到 1 的不同睡眠时间(例如 [NSThread sleepForTimeIntervals .1]).尽管如此,屏幕显示充其量是迟缓的(10 秒),按下停止按钮会突出显示该按钮,但在 10 秒内什么也没有发生.

1.) NSOperation 队列是一个合理的选择吗?如果没有,还有什么?2.) 如何减少睡眠?(显然,我希望工作获得尽可能多/合理的周期,而且我不确定我的睡眠是否对所有 UI 更新有任何影响.)3.) 有没有更好的技术让 UI 保持最新?例如,我可以使用 NSTimer 或其他方法向 UI 发送消息,告诉它更新和/或检查按钮的状态吗?

感谢您的支持.

推荐答案

1.) NSOperation 队列是一个合理的选择吗?如果没有,还有什么?

NSOperationQueue 听起来很合理.

当然,您可以选择:pthreads、libdispatch(又名 GCD)、建立在 pthreads 之上的 c++ 线程库等,等等.你喜欢的模特.

<块引用>

2.) 如何减少睡眠?(显然,我希望工作获得尽可能多的周期/合理,而且我不确定我的睡眠是否对所有要更新的 UI 做任何事情.)

不要睡觉 =) 您可以为您的 ui 元素使用计时器或显式回调或通知来通知依赖项.如果依赖项执行 ui 更新,那么您可能会将消息添加到主线程的消息队列中.

<块引用>

3.) 是否有更好的技术来使 UI 保持最新状态?例如,我可以使用 NSTimer 或其他方法向 UI 发送消息,告诉它更新和/或检查按钮的状态吗?

这真的取决于你在做什么.如果您只想更新进度条,则可以从辅助线程写入值并从主线程读取值.然后在主运行循环上使用计时器定期向您的对象发送消息以更新其显示(基于当前值).对于诸如未分级的进度指示器之类的东西,这可能很好.

另一种选择对事件或阶段更有用:它将涉及随着进度的进行从辅助线程发布更新(例如通知或对委托的回调)(更多信息在 #2 下).

更新

<块引用>

我不确定这在 iOS 模型中是否合适,但听起来确实如此.

是的,这很好 - 您可以采取许多方法.哪个是"最好的"取决于上下文.

<块引用>

我目前的理解是在一个线程中启动 UI(不是主线程!),

您确实没有明确启动 UI;主线程(通常)通过将事件和消息推送到主线程来驱动.主线程使用运行循环并在运行循环的每次迭代中处理排队的消息/事件.您还可以在将来安排这些消息(稍后会详细介绍).话虽如此,您对 UIKit 和 AppKit(如果您以 osx 为目标)对象的所有消息都应该在主线程上(作为概括,您最终会了解到这有例外).如果您有一个与消息传递 UIKit 对象的方法完全分离的特定实现,并且该程序是线程安全的,那么您实际上可以从任何线程执行这些消息,因为它不会影响 UIKit 实现的状态.最简单的例子:

@interface MONView : UIView
@end

@implementation MONView
// ...
- (NSString *)iconImageName { return @"tortoise.png"; } // pure and threadsafe
@end
<块引用>

启动我的工作线程,使用计时器向 UI 生成信号以查看进度值并适当地更新进度条.出于这个特定应用程序的目的,您的倒数第二段已经足够了,我不需要深入到最后一段的长度(至少现在是这样).谢谢.

为此,您可以使用类似的方法:

@interface MONView : UIView
{
    NSTimer * timer;
    MONAsyncWorker * worker; // << this would be your NSOperation subclass, if you use NSOperation.
}

@end

@implementation MONView

// callback for the operation 'worker' when it completes or is cancelled.
- (void)workerWillExit
{
    assert([NSThread isMainThread]); // call on main

    // end recurring updates
    [self.timer invalidate];
    self.timer = nil;

    // grab what we need from the worker
    self.worker = nil;
    // update ui
}

// timer callback
- (void)timerUpdateCallback
{
    assert([NSThread isMainThread]); // call on main
    assert(self.worker);

    double progress = self.worker.progress;

    [self updateProgressBar:progress];
}

// controller entry to initiate an operation
- (void)beginDownload:(NSURL *)url
{
    assert([NSThread isMainThread]); // call on main
    assert(nil == worker); // call only once in view's lifetime

    // create worker
    worker = [[MONAsyncWorker alloc] initWithURL:url];
    [self.operationQueue addOperation:worker];

    // configure timer
    const NSTimeInterval displayUpdateFrequencyInSeconds = 0.200;
    timer = [[NSTimer scheduledTimerWithTimeInterval:displayUpdateFrequencyInSeconds target:self selector:@selector(timerUpdateCallback) userInfo:nil repeats:YES] retain];
}

@end

请注意,这是一个非常原始的演示.将计时器、更新处理和操作放在视图的控制器而不是视图中也更常见.

本文地址:https://www.itbaoku.cn/post/924358.html