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

2023-11-21

在我的应用程序中,我在 NSOperationQueue 中执行 10 个异步 NSURLConnections 作为 NSInitationOperations。为了防止每个操作在连接有机会完成之前返回,我调用 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];
}

连接完成后,最终的连接委托选择器调用 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 所需的速度。具体来说,表视图滚动变得不稳定。

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 Sampler 来检测和修复影响主线程性能的问题的指南。感谢迄今为止的评论,它们很有帮助!

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

最终我将 NSURLConnection 替换为ASIHTTP请求撞击声完全停止了。 CF网络almost永远不会泄漏,但是,在解析 DNS 名称时仍然会发生一种非常罕见的泄漏。我现在已经很满意了。希望这些信息可以为您节省一些时间!


实际上,您根本无法拥有超过两个或三个后台网络线程并且让 UI 保持完全响应。

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

iPhone 3GS 上后台线程消耗 100% CPU 导致潜在主线程 的相关文章

  • 在 iOS 中,如何以编程方式填写 pdf 表单字段?

    我需要获取一个现有的 pdf 文件 并以编程方式填写带有文本的表单字段列表 然后保存 pdf 而不将其显示给用户 例如 如果 pdf 文件包含名为 LastName 和 FirstName 的字段 我想将 FirstName 的值设置为 L
  • 多线程 - 比单线程慢

    当我使用多个线程而不是单线程运行程序时 它会变慢 不是应该更快吗 该程序应该遍历从起始目录开始的所有目录 并查找并打印所有名为 X 的文件 代码如下 while done pthread mutex lock lock if list is
  • TestFlight Beta 中的消息不可用

    I am seeing Unavailable message in TestFLight Beta App in iOS8 Please find the attached screenshot please tell me how to
  • iOS 低内存崩溃,但内存使用率非常低

    这已经困扰我很长时间了 我的应用程序运行占用大约 2 74MB 内存 没关系 但当它创建 UIWebView 时 它会增加到大约 5 87MB 并继续崩溃 这些是在我的第一代 iPad 上运行时仪器中的实时字节下给出的值 我找不到崩溃日志
  • 从本机 iPhone 应用程序访问 UIWebView 本地存储数据

    我正在编写一个包含 UIWebView 组件的本机 iPhone 应用程序 该组件访问互联网 Web 应用程序 并且该 Web 应用程序使用 HTML5 本地存储离线存储数据 是否可以从本机应用程序访问此本地存储数据 我想做类似的事情 简而
  • iOS后台获取时间限制崩溃

    我已经设置了背景获取 使用大纲NSScreencast 第 92 集 http nsscreencast com episodes 92 background fetch BOOL application UIApplication app
  • C# 为所有对象订阅相同的事件处理程序是线程安全的吗

    我的项目中有一种情况 我连接到多个服务器并监听事件 每当从服务器接收到事件时 Handler 就应该将该事件添加到公共队列中进行处理 所有连接都应将接收到的事件添加到队列中 foreach var item in collection Co
  • nHibernate 使用 Log4Net 进行日志记录,线程会话问题

    大家好 这里有一个小问题 我正在努力解决这个问题 我目前正在开始使用 nHibernate 由于工作需要 我不得不这样做 并且我在 nHibernate 的会话和多线程方面遇到了一些困难 我想在这里完成的任务是让 Log4Net 将所有内容
  • NSString 对象的最大长度是多少?

    NSString 对象中可以保存的最大字符串大小是多少 这会动态变化吗 我假设 NSString 的硬限制是 NSUIntegerMax 个字符 因为 NSString 的索引和大小相关的方法返回 NSUInteger 由于当前能够运行 i
  • 为什么 iPhone 应用程序的 main() 函数没有机会完成?

    考虑以下main 大多数 iPhone 应用程序都采用以下方法 int main int argc char argv NSAutoreleasePool pool NSAutoreleasePool alloc init int retV
  • 使用 JSONKit 解析 JSON 文件

    我正在构建一个音叉应用程序 货叉应允许最多 12 个预设节距 此外 我希望允许用户选择一个主题 每个主题都会加载一组预设 不必使用所有预设 我的配置文件看起来像这样 theme A3 comment An octave below conc
  • iOS 上关键 ClientState 警告的默认访问速度缓慢

    在测试我的 iOS 应用程序时 我收到 对关键 ClientState 的默认访问速度慢 耗时 0 034635 秒 容差为 0 020000 警告 它似乎是间歇性发生的 我试图环顾四周看看它是关于什么的 但我并不完全确定 任何帮助表示赞赏
  • Boost:如何创建一个线程以便可以控制它的所有标准输出、标准错误?

    我用 C 创建了一个 win32 控制台应用程序 我使用一些API 不是我的 我不能修改它的来源 它是这样写的 它会将一些信息写入控制台屏幕 而不询问 每次我调用它时 每秒 48 次 所以我想将它放入某个线程并限制其输出能力 但我需要得到当
  • 为什么 Apple 建议以编程方式创建模态导航控制器?

    以模态方式呈现导航控制器时 以编程方式创建和配置导航控制器对象通常更简单 虽然您也可以使用 Interface Builder 来执行此操作 但通常不建议这样做 事实上 因为我的导航控制器很简单 我宁愿在IB中自定义视图 虽然我不知道确切的
  • iPhone Dev:从子控制器和 TabBar 中的另一个控制器重新加载表视图的数据

    我正在实现一个笔记管理器应用程序 它在 tabBar 中有一个 tableView 其中显示其笔记的主要信息 访问一个注释时 您可以编辑其属性 在 tabBar 的一个按钮中 您可以选择注释在 tableView 中的显示方式 我遇到的问题
  • 增加 iPhone 的推送通知徽章

    是否可以在收到通知时增加徽章值 或者我应该将计数作为有效负载发送吗 如果我每次都将徽章值发送为 1 那么如果应用程序未打开 我如何增加应用程序图标中的徽章值 我已经使用了这段代码 但不起作用 void application UIAppli
  • 移动物体而不实际接触物体

    我是 iPhone 开发的初学者 我一直在寻找这个问题的答案 但还没有找到任何东西 我想做的是允许用户移动对象而无需实际触摸该对象 他们可以触摸屏幕上的任何位置 并且当他们移动时 对象将从原来的位置向用户的方向移动移动但不会跳到他们的触摸位
  • iOS 搜索栏不显示结果

    更新 这实际上有效 我的自定义单元格的样式尚未出现 因此单元格看起来是空白的 那我怎样才能得到searchResultsTableView使用我的自定义单元格 我在表格视图中实现了搜索栏 当我调试时搜索 过滤所有工作 但是当我在搜索栏中输入
  • 刷新单元格的 UITableView 队列

    我想知道如果调用 UITableView reloadData 时 UITableView 队列被刷新 是否有人可以回复我 我正在尝试这样做 但这对我没有帮助 有什么建议吗 如果你查看 UITableView 的头文件 你可以看到有一个名为
  • 带有自定义字体的 UILabel 错误呈现

    在我的 iPhone 应用程序中 我为所有 UILabel 设置了自定义字体 更准确地说 我对 UILabel 进行了子类化 重写了一个方法 在该方法中设置了自定义字体 然后将 IB 中的所有标签设置为该自定义类 现在的问题是 所有文本都渲

随机推荐

  • Strapi CMS:获取嵌套内容

    我正在使用 Strapi CMS 并努力获取嵌套 深层内容的数据 例如 假设我创建了以下内容类型并定义了关系 人物 姓名 年龄 地址 城市 国家 联系方式 代码 号码 一个人有一个地址 地址有很多联系人 现在的问题是 当我访问 person
  • 错误共享和原子变量

    当不同的变量位于同一个缓存行内时 您可以体验到虚假分享 这意味着即使两个不同的线程 在不同的内核上运行 正在访问两个不同的变量 如果这两个变量驻留在同一缓存行中 您也会受到性能影响 因为每次都会触发缓存一致性 现在说这些变量是原子变量 我所
  • 如何通过引用正确传递 Integer 类?

    我希望有人能为我澄清这里发生的事情 我在整数类中进行了一些研究 但是因为整数是压倒性的 the 操作员我无法弄清楚出了什么问题 我的问题是这一行 Integer i 0 i i 1 I think that this is somehow
  • 有黑莓浏览器模拟器吗?

    我正在开发一个需要在黑莓浏览器中运行的移动网站 这不是一个应用程序 只是一个带有自定义样式表的网站 是否有可用的 Blackberry 浏览器模拟器 或者我是否需要使用其中一个模拟器来为您提供整个 BB 系统 是的 你必须使用模拟器由 RI
  • 如何在 presto 中将 varchar 转换为 MAP(VARCHAR,VARCHAR)

    我在 presto 中有一个表 名为 映射 的一列将键值对作为字符串 从 hello 中选择映射 例如 foo baar foo1 bar1 我想将 映射 列转换为 MAP 就像从 hello 中选择 CAST mappings as MA
  • C++ cout 给出未声明的标识符

    所以 我有这个问题 为什么 cout 会抛出异常 error C2065 cout undeclared identifier 我正在使用 Visual Studio 2012 作为 IDE 并且正在编写一个学校项目 除了示例文件之外 我已
  • 在没有 xorg 的 Linux 上运行 chrome headless

    是否可以在无头 Linux 机器上安装和运行 chrome headless 而无需安装音频和 xorg 依赖项 如果没有 那么是否有一个特殊的 chrome chromium 无头版本 它不会提取 xorg 和音频库 这个关于 puppe
  • Spring boot - MySQL 设置不起作用

    我正在尝试使用 Spring boot 和 MySQL 开发一个应用程序 正如文档所说 首先我使用 Intelij Idea 使用 Springinitializr 创建了项目 配置了application properties文件 并写道
  • 如何动态更改 Crypt 在 Laravel 中使用的密钥?

    我一直在研究如何使用Laravel 加密因为建立一个宅基地加密平台是不受欢迎的 也是理所当然的 Illuminate Support Facades Crypt encryptString This is a secret message
  • 从量角器激活时激活 chrome 语言标志(selenium)

    我正在使用 Protractor 为一个有角度的网站编写端到端测试 我们必须支持某些语言 所以我想使用以下命令来初始化 chrome lang标记并用其他语言启动它 我搜索了网络 但找不到任何有关如何完成此操作的示例 我唯一的线索是我看到并
  • Jitsi SIP Communicator 安装程序

    在完成更改后 我必须为 Jitsi SIP Communicator 创建安装程序 我在网上搜索并发现了一些步骤 如下所示 软件要求 西格温 包含库 make gcc 和 g http cygwin com setup exe 明GW 仅
  • 使用内联CSS - 在某些情况下是禁忌还是可以? [复制]

    这个问题在这里已经有答案了 可能的重复 内联样式与 CSS 中的样式 我想我正在寻找对此的一些意见 我完全赞成在单独的 css 文件中使用 css 样式作为类 但每隔一段时间 我就会遇到一种情况 我只需要为特定元素进行一些填充 或者仅在一种
  • 使用.NET捕获屏幕截图[重复]

    这个问题在这里已经有答案了 可能的重复 如何以位图形式捕获屏幕 我需要制作一个应用程序 每当按下特定按钮时都会捕获当前屏幕的快照 我搜索了很多 但只找到了如何捕获当前窗口 您能帮我弄清楚如何在 NET 中执行此操作吗 我们可以通过点击打印屏
  • mysql RAND() 限制

    您好 我有一个这样的查询 SELECT otel id FROM YAZILIM menu icerik WHERE YAZILIM menu icerik menu id 39 AND otel id IN SELECT otel id
  • 比较 Javascript 中的日期和时区

    当使用 gt 和 当您将其转换为 JavaScript 时 将按照您的预期考虑时间戳字符串表示形式的时区部分Date对象 内部值是一个简单的标量 标准化为UTC 所以比较时不需要特殊的时区处理Date对象 var d1 new Date D
  • Javascript 日期,这是我的错误还是我发现了错误?

    我的应用程序中有一个简单的 Javascript 部分 其中有一个链接 添加日期 它会在日期上添加 1 天 它总是工作得很好 除非日期是 11 07 2010 然后链接突然不再工作 它真的很奇怪 因为它只在特定日期 11 07 2010 挂
  • GCC 编译时抛出错误:错误:未知类型名称“FILE”

    我正在制作一个只写的函数 hello 到一个文件 我已将其放在另一个文件中 并将其标头包含在程序中 但 gcc 给出了一个错误 error unknown type name FILE 代码如下 app c include
  • 缩放 SKNode 不一致

    我已经创建了自己的解决方案 用于放大或缩小特定的 SKNode 而无需缩放整个场景 它似乎主要按照我期望的方式工作 有 2 个值得注意的例外 我希望在这里得到输入 首先是代码 该控制语句位于touchesMoved方法内 if touche
  • 使用jquery更改给定特定宽度范围的类名(媒体查询)

    我正在尝试修改以下 html div class col1 width8 img src images entity jpg div 我想使用媒体查询 但我不想修改css 而是将类名从width8替换为width6 对于下面的标准媒体查询来
  • iPhone 3GS 上后台线程消耗 100% CPU 导致潜在主线程

    在我的应用程序中 我在 NSOperationQueue 中执行 10 个异步 NSURLConnections 作为 NSInitationOperations 为了防止每个操作在连接有机会完成之前返回 我调用 CFRunLoopRun