gpt4 book ai didi

iphone - 在 iOS 上管理 CPU 密集型线程

转载 作者:可可西里 更新时间:2023-11-01 05:04:53 25 4
gpt4 key购买 nike

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

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

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

感谢您的支持。

最佳答案

1.) Are NSOperation Queues a reasonable choice? If not, what else?

NSOperationQueue 听起来很合理。

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

2.) How do I minimize the sleeping? (Obviously I want the work to get as many cycles as possible/reasonable, and I’m not sure that my sleeps are doing anything at all to all the UI to update.)

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

3.) Is there a better technique to keep the UI up to date? For instance, can I use NSTimer or some other method to send a message to the UI telling it to update and/or check the status of the buttons?

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

另一种选择对事件或阶段更有用:它涉及在取得进展时从辅助线程发布更新(例如通知或回调到委托(delegate))(#2 下的更多信息)。

更新

I wasn't sure this was appropriate in the iOS model, but it sounds like it is.

是的,没关系 - 您可以采用多种方法。哪个“最好”取决于上下文。

My current understanding is to launch the UI in one thread (not the main!),

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

@interface MONView : UIView
@end

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

launch my worker thread, use a timer to generate a signal to the UI to take a look at a progress value and update the progress bar appropriately. For the purposes of this particular application your second to last paragraph is ample and I don't need to go to the lengths of the last paragraph (at least for now). Thank you.

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

@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

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

关于iphone - 在 iOS 上管理 CPU 密集型线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7409064/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com