- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我是一位经验丰富的 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/
IO 设备如何知道属于它的内存中的值在memory mapped IO 中发生了变化? ? 例如,假设内存地址 0 专用于保存 VGA 设备的背景颜色。当我们更改 memory[0] 中的值时,VGA
我目前正在开发一个使用Facebook sdk登录(通过FBLoginView)的iOS应用。 一切正常,除了那些拥有较旧版本的facebook的人。 当他们按下“使用Facebook登录”按钮时,他
假设我有: this - is an - example - with some - dashesNSRange将使用`rangeOfString:@“-”拾取“-”的第一个实例,但是如果我只想要最后
Card.io SDK提供以下详细信息: 卡号,有效期,月份,年份,CVV和邮政编码。 如何从此SDK获取国家名称。 - (void)userDidProvideCreditCardInfo:(Car
iOS 应用程序如何从网络服务下载图片并在安装过程中将它们安装到用户的 iOS 设备上?可能吗? 最佳答案 您无法控制应用在用户设备上的安装,因此无法在安装过程中下载其他数据。 只需在安装后首次启动应
我曾经开发过一款企业版 iOS 产品,我们公司曾将其出售给大型企业,供他们的员工使用。 该应用程序通过 AppStore 提供,企业用户获得了公司特定的配置文件(包含应用程序配置文件)以启用他们有权使
我正在尝试将 Card.io SDK 集成到我的 iOS 应用程序中。我想为 CardIO ui 做一个简单的本地化,如更改取消按钮标题或“在此保留信用卡”提示文本。 我在 github 上找到了这个
我正在使用 CardIOView 和 CardIOViewDelegate 类,没有可以设置为 YES 的 BOOL 来扫描 collectCardholderName。我可以看到它在 CardIOP
我有一个集成了通话工具包的 voip 应用程序。每次我从我的 voip 应用程序调用时,都会在 native 电话应用程序中创建一个新的最近通话记录。我在 voip 应用程序中也有自定义联系人(电话应
iOS 应用程序如何知道应用程序打开时屏幕上是否已经有键盘?应用程序运行后,它可以接收键盘显示/隐藏通知。但是,如果应用程序在分屏模式下作为辅助应用程序打开,而主应用程序已经显示键盘,则辅助应用程序不
我在模拟器中收到以下错误: ImageIO: CGImageReadSessionGetCachedImageBlockData *** CGImageReadSessionGetCachedIm
如 Apple 文档所示,可以通过 EAAccessory Framework 与经过认证的配件(由 Apple 认证)进行通信。但是我有点困惑,因为一些帖子告诉我它也可以通过 CoreBluetoo
尽管现在的调试器已经很不错了,但有时找出应用程序中正在发生的事情的最好方法仍然是古老的 NSLog。当您连接到计算机时,这样做很容易; Xcode 会帮助弹出日志查看器面板,然后就可以了。当您不在办公
在我的 iOS 应用程序中,我定义了一些兴趣点。其中一些有一个 Kontakt.io 信标的名称,它绑定(bind)到一个特定的 PoI(我的意思是通常贴在信标标签上的名称)。现在我想在附近发现信标,
我正在为警报提示创建一个 trigger.io 插件。尝试从警报提示返回数据。这是我的代码: // Prompt + (void)show_prompt:(ForgeTask*)task{
您好,我是 Apple iOS 的新手。我阅读并搜索了很多关于推送通知的文章,但我没有发现任何关于 APNS 从 io4 到 ios 6 的新更新的信息。任何人都可以向我提供 APNS 如何在 ios
UITabBar 的高度似乎在 iOS 7 和 8/9/10/11 之间发生了变化。我发布这个问题是为了让其他人轻松找到答案。 那么:在 iPhone 和 iPad 上的 iOS 8/9/10/11
我想我可以针对不同的 iOS 版本使用不同的 Storyboard。 由于 UI 的差异,我将创建下一个 Storyboard: Main_iPhone.storyboard Main_iPad.st
我正在写一些东西,我将使用设备的 iTunes 库中的一部分音轨来覆盖 2 个视频的组合,例如: AVMutableComposition* mixComposition = [[AVMutableC
我创建了一个简单的 iOS 程序,可以顺利编译并在 iPad 模拟器上运行良好。当我告诉 XCode 4 使用我连接的 iPad 设备时,无法编译相同的程序。问题似乎是当我尝试使用附加的 iPad 时
我是一名优秀的程序员,十分优秀!