Objective-C 中的异步调用

2023-11-26

我正在尝试从网站 xml 获取数据。一切正常。

但是 UIButton 一直处于按下状态,直到返回 xml 数据,因此如果互联网服务出现问题,则无法纠正,并且应用程序实际上无法使用。

以下是通话内容:

{
    AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    if(!appDelegate.XMLdataArray.count > 0){
        [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
        [appDelegate GetApps]; //function that retrieves data from Website and puts into the array - XMLdataArray.
    }
    XMLViewController *controller = [[XMLViewController alloc] initWithNibName:@"MedGearsApps" bundle:nil];
    [self.navigationController pushViewController:controller animated:YES];
    [controller release];
}

它工作得很好,但是我怎样才能使视图按钮在卡住的情况下发挥作用。换句话说,我只希望 UIButton 和其他 UIButton 能够在后台工作时发挥作用。

我听说过performSelectorInMainThread但我无法正确地实践它。


您不太了解线程模型,如果您在没有真正了解发生了什么的情况下开始添加异步代码,您可能会搬起石头砸自己的脚。

您编写的代码在主应用程序线程中运行。但当你想一想,你不必写“不”main函数 - 您只需实现应用程序委托和事件回调(例如触摸处理程序),并且它们会在时间到来时自动运行。这不是魔法,这只是一个名为 a 的 Cocoa 对象Run Loop.

Run Loop 是一个接收所有事件、处理计时器的对象(如NSTimer)并运行您的代码。这意味着,例如,当您在用户点击按钮时执行某些操作时,调用树看起来有点像这样:

main thread running
    main run loop
        // fire timers
        // receive events — aha, here we have an event, let’s call the handler
        view::touchesBegan…
            // use tapped some button, let’s fire the callback
            someButton::touchUpInside
                yourCode

Now yourCode做你想做的事情并且运行循环继续运行。但是,当您的代码需要很长时间才能完成时(例如您的情况),运行循环必须等待,因此在代码完成之前不会处理事件。这就是您在应用程序中看到的内容。

要解决这种情况,您必须在另一个线程中运行长操作。这并不难,但您仍然必须考虑一些潜在的问题。在另一个线程中运行就像调用一样简单performSelectorInBackground:

[appDelegate performSelectorInBackground:@selector(GetApps) withObject:nil];

现在您必须想办法告诉应用程序数据已加载,例如使用通知或在主线程上调用选择器。顺便说一句:将数据存储在应用程序委托中(或者甚至使用应用程序委托来加载数据)并不是非常优雅的解决方案,但那是另一个故事了。

如果您选择performSelectorInBackground解决方案,看一下相关问题辅助线程中的内存管理。您需要自己的自动释放池,这样就不会泄漏自动释放的对象。


一段时间后更新答案——现在通常最好使用 Grand Central Dispatch 在后台运行代码:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    // No explicit autorelease pool needed here.
    // The code runs in background, not strangling
    // the main run loop.
    [self doSomeLongOperation];
    dispatch_sync(dispatch_get_main_queue(), ^{
        // This will be called on the main thread, so that
        // you can update the UI, for example.
        [self longOperationDone];
    });
});
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Objective-C 中的异步调用 的相关文章

随机推荐

  • vim 中可以对一组行进行排序吗?

    据我所知 vim 的 sort 方法会对每一行进行排序 我有一些代码以 3 行为一组 我该如何排序 请忽略那些糟糕的代码 它是一个遗留应用程序 我想按大小写 AF 行排序 但忽略 分组 国家 地区并换行 case AF country Af
  • 使用 Dagger 2 在库模块中注入应用程序上下文

    我正在构建一个具有一些功能的应用程序 ContentProvider SyncAdapter 作业服务和相关的持久性逻辑 在这些之上是带有 UI 的活动 我试图将所有上述功能放在一个单独的库模块中 因为理论上它们的逻辑是独立的并且可以由任何
  • MSI 错误 - regsvr32 自定义操作失败

    Brief 我有一个安装包 基于 MSI 它尝试注册一个 dll 文件以用作 Windows 资源管理器栏 Internet Explorer 工具栏 自定义动作定义如下 SystemFolder regsvr32 exe s pathto
  • 将字体嵌入 Apache FOP

    我试图让 Apache FOP 使用 Arial 作为字体 到目前为止 还没有运气 在我的 config xml 中它说
  • 使用 inferred_freq 设置 pandas.tseries.index.DatetimeIndex.freq

    考虑DatetimeIndex tidx tidx pd to datetime 2016 07 29 2016 08 31 2016 09 30 print tidx freq print tidx inferred freq print
  • 使用 Boost.Asio 执行干净关闭的标准方法

    我正在使用 Boost Asio 用 C 编写一个跨平台服务器程序 按照 HTTP 服务器示例这一页 我想在不使用特定于实现的 API 的情况下处理用户终止请求 我最初尝试使用标准 C 信号库 但一直无法找到适合 Asio 的设计模式 这W
  • 如何将Shiny应用程序中的表格和绘图作为参数传递给R Markdown?

    在此 Shiny 应用程序中 用户可以上传 csv 文件 以表格和绘图的形式获取结果 我希望能够将结果下载为 PDF 文档 输入文件 I created the input csv file to be used in the app fr
  • Rcpp::compileAttributes() 错误

    我正在尝试编译我制作的一个小包 该包使用 Rcpp 和 RcppArmadillo 一切都运行良好 直到我将我的 Mac 更新到 Sierra 版本 10 12 5 从 Rstudio 版本 1 0 143 构建包时 我现在收到以下错误消息
  • SignalR 不支持 Windows 集成身份验证

    我有一个 ASP NET MVC 4 应用程序 NET 4 5 SIignalR 可以很好地处理基于表单的身份验证 通过 IIS IIS Express 托管 一旦我将应用程序更改为 Windows 集成身份验证
  • 部署到 Elastic Beanstalk 时运行 Django 迁移

    我在 Elastic Beanstalk 上设置了 Django 应用程序 最近对数据库进行了更改 我希望现在将其应用到实时数据库 我知道我需要将其设置为容器命令 在检查数据库后我可以看到迁移已运行 但我不知道如何对迁移进行更多控制 例如
  • 如何获取当前正在显示的tableView的indexPath.row?

    我有一个包含许多值的 tableView 我想获得第一indexPath row当前正在显示的表的值 我怎样才能做到这一点 我在实现 krishnabhadra 的答案时遇到以下错误 出现错误的行是 self table scrollToR
  • urllib 下载在线目录的内容

    我正在尝试制作一个程序 该程序将打开一个目录 然后使用正则表达式来获取幻灯片的名称 然后在本地创建文件并复制其内容 当我运行它时 它似乎可以工作 但是当我实际尝试打开文件时 他们一直说版本错误 from urllib request imp
  • 将 awk 与列值条件结合使用

    我正在学习 awkAWK 编程语言我对其中一个例子有疑问 如果我想打印 3 如果 2 等于一个值 例如1 我正在使用这个运行良好的命令 awk 2 1 print 3
  • 从 angularjs 中的服务调用控制器函数

    我正在使用 socket io 在我的应用程序中启用聊天 并且我正在使用一项服务SocketService执行所有套接字操作 当消息到来时 我想从服务触发控制器的功能SocketService对 UI 进行一些更改 所以我想知道如何从服务访
  • 如何在 redux 操作(或操作中分配的其他回调)上下文中使用 jest 测试 `image.onload`

    我的问题是我正在尝试对一个函数进行单元测试 但不知道如何测试它的一部分 这是一个 React Redux 操作 执行以下操作 1 使用图像 url 检索 json 数据 2 将图像加载到 Image 实例中并将其大小分派给减速器 当使用 I
  • document.write 的替代品是什么?

    在教程中我学会了使用document write 现在我明白 许多人对此不以为然 我试过了print 但随后它实际上将其发送到打印机 那么我应该使用什么替代方案 为什么我不应该使用document write w3schools 和 MDN
  • JavaScript 中现有的 OCR 脚本 [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 目前不接受答案 我有一个 CMS 增强功能的想法 从图像 例如扫描文档 中提取文本信息 并且想知道是否已经有任何东西可以帮助我 基本上 我想知道是否有一个用 Jav
  • 当iframe的来源是javascript时浏览器会做什么

    当 iframe 的来源是 javascript as in 到底是怎么回事 src javascript 是什么意思告诉浏览器做什么 path src 有什么作用 谢谢 克里斯 它告诉浏览器显示执行空字符串文字的结果 因此 它只会显示一个
  • 如何在客户端检查 YouTube 上是否存在视频

    我在做验证我的Youtube网址文本字段 我需要检查一下 如果Youtubeurl不存在我应该抛出错误 我按照这个answer并创建了jsfiddle检查它 它适用于有效的 url 但不适用于无效的 url 我所看到的只是 404 错误ne
  • Objective-C 中的异步调用

    我正在尝试从网站 xml 获取数据 一切正常 但是 UIButton 一直处于按下状态 直到返回 xml 数据 因此如果互联网服务出现问题 则无法纠正 并且应用程序实际上无法使用 以下是通话内容 AppDelegate appDelegat