gpt4 book ai didi

iphone - 后台线程在 iPhone 3GS 上消耗 100% CPU 导致潜在的主线程

转载 作者:太空狗 更新时间:2023-10-30 03:26:25 24 4
gpt4 key购买 nike

在我的应用程序中,我在 NSOperationQueue 中执行 10 个异步 NSURLConnections 作为 NSInvocationOperations。为了防止每个操作在连接有机会完成之前返回,我调用 CFRunLoopRun() 如下所示:

- (void)connectInBackground:(NSURLRequest*)URLRequest {
TTURLConnection* connection = [[TTURLConnection alloc] initWithRequest:URLRequest delegate:self];

// Prevent the thread from exiting while the asynchronous connection completes the work. Delegate methods will
// continue the run loop when the connection is finished.
CFRunLoopRun();

[connection release];
}

一旦连接完成,最终连接委托(delegate)选择器调用CFRunLoopStop(CFRunLoopGetCurrent())恢复connectInBackground()中的执行,使其正常返回:

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
TTURLConnection* ttConnection = (TTURLConnection*)connection;
...
// Resume execution where CFRunLoopRun() was called.
CFRunLoopStop(CFRunLoopGetCurrent());
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
TTURLConnection* ttConnection = (TTURLConnection*)connection;
...
// Resume execution where CFRunLoopRun() was called.
CFRunLoopStop(CFRunLoopGetCurrent());
}

这很好用并且是线程安全的,因为我将每个连接的响应和数据作为实例变量捆绑在 TTURLConnection 子类中。

NSOperationQueue 声称将其最大并发操作数保留为 NSOperationQueueDefaultMaxConcurrentOperationCount 允许它动态调整操作数,但是,在这种情况下,它始终认为 1 就足够了。由于这不是我想要的,我已将最大数量更改为 10,现在它真的很拖拉。

问题在于这些线程(在 SpringBoard 和 DTMobileIS 的帮助下)消耗了所有可用的 CPU 时间并导致主线程变为延迟。换句话说,一旦 CPU 被 100% 使用,主线程就不会以保持流畅的 UI 所需的速度处理 UI 事件。具体来说,表格 View 滚动变得不稳定。

Process Name  % CPU
SpringBoard 45.1
MyApp 33.8
DTMobileIS 12.2
...

当用户与屏幕交互或表格滚动时,主线程的优先级变为 1.0(最高可能)并且其运行循环模式变为 UIEventTrackingMode。默认情况下,每个操作的线程都是 0.5 优先级,并且异步连接在 NSDefaultRunLoopMode 中运行。由于我对线程及其运行循环如何根据优先级和模式进行交互的了解有限,我感到很困惑。

有没有一种方法可以在我的应用程序的后台线程中安全地消耗所有可用的 CPU 时间,同时仍然保证为其主线程提供所需的尽可能多的 CPU?也许通过强制主线程按需要运行? (我认为线程优先级会解决这个问题。)

12 月 23 日更新:我终于开始了解 CPU 采样器并找到了 UI 变得不稳定的大部分原因。首先,我的软件正在调用一个具有互斥信号量的库。这些锁会在短时间内阻塞主线程,导致滚动略微跳过。

此外,我发现一些昂贵的 NSFileManager 调用和 md5 哈希函数运行时间过长。过于频繁地分配大对象会导致主线程中的其他一些性能下降。

我已经着手解决这些问题,性能已经比以前好很多了。我有 5 个同时连接并且滚动很流畅,但我还有更多工作要做。我打算写一篇关于如何使用 CPU 采样器来检测和修复影响主线程性能的问题的指南。感谢到目前为止的评论,它们很有帮助!

2010 年 1 月 14 日更新:在达到可接受的性能后,我开始意识到 CFNetwork 框架偶尔会泄漏内存。 CFNetwork 内部也会随机(但是很少)引发异常!我尽我所能避免这些问题,但没有任何效果。我很确定这些问题是由于 NSURLConnection 本身的缺陷造成的。我编写的测试程序除了运行 NSURLConnection 之外什么都不做,但它们仍然崩溃和泄漏。

最终我将 NSURLConnection 替换为 ASIHTTPRequest崩溃完全停止了。 CFNetwork 几乎 从不泄漏,但是,在解析 DNS 名称时仍然会发生非常罕见的泄漏。我现在很满意。希望这些信息能为您节省一些时间!

最佳答案

在实践中,您不能简单地拥有两个或三个以上的后台网络线程并让 UI 保持完全响应。

针对用户响应进行优化,这是用户真正注意到的唯一事情。或者(我真的不想这么说)在您的应用程序中添加一个“Turbo”按钮,该按钮会显示一个非交互式模式对话框,并在它启动时将并发操作增加到 10 个。

关于iphone - 后台线程在 iPhone 3GS 上消耗 100% CPU 导致潜在的主线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1940903/

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