如何在 Objective-C 中包装采用块的异步方法并将其转换为同步

2024-02-17

我想包装一个如下所示的异步 API:

[someObject completeTaskWithCompletionHandler:^(NSString *result) {

}];

进入一个同步方法,我可以这样调用:

NSString *result = [someObject completeTaskSynchronously];

我该怎么做呢?我做了一些文档阅读和互联网搜索,并尝试使用“dispatchsemaphore”来尝试实现它,如下所示:

-(NSString *) completeTaskSynchronously {
   __block NSString *returnResult;
   self.semaphore = dispatch_semaphore_create(0);  
   [self completeTaskWithCompletionHandler:^(NSString *result) {
       resultResult = result;
       dispatch_semaphore_signal(self.semaphore);
   }];

   dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
   return resultResult;
}

但这似乎不起作用,它基本上只是停在dispatch_semaphore_wait。执行永远不会到达执行 _signal 的内部块。有人有关于如何执行此操作的代码示例吗?我怀疑该块必须位于主线程之外的不同线程上?另外,假设我无权访问异步方法背后的源代码。


dispatch_semaphore_wait在您的示例中阻塞主队列。您可以将异步任务分派到不同的队列:

__block NSString *returnResult;
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0UL);
dispatch_async(queue,^{
     result = [someObject completeTaskSynchronously];
});

或者使用其他系统,例如 NSRunLoop:

   __block finished = NO;
   [self completeTaskWithCompletionHandler:^(NSString *result) {
       resultResult = result;
       finished = YES;
   }];
    while (!finished) {
        // wait 1 second for the task to finish (you are wasting time waiting here)
        [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:1]];
    }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Objective-C 中包装采用块的异步方法并将其转换为同步 的相关文章

  • Objective-C 实例变量?

    我确信我在这里的困惑只是因为陷入 Java 思维方式 并且不理解 Obj C 在这种情况下有何不同 在Java中 我可以在类中声明一个变量 就像这样 并且每个instance该类的 将会有它自己的 MyClass String myVar
  • 在界面生成器/故事板中设置 UIButton 图像

    我有一个视图控制器 我在故事板中添加了一个圆形矩形按钮 该应用程序运行良好 我还使用故事板将按钮连接到 segue 我正在尝试为此按钮设置一个自定义图像以用于其开和关状态 我如何访问此按钮并设置其属性 在本例中为开和关图像 这是一个屏幕截图
  • Firebase 连接管理器应仅返回一个结果

    我正在关注位于以下位置的文档 https www firebase com docs ios guide offline capability html section connection state https www firebase
  • 如何等待 webViewDidFinishLoad 完成

    我有一个初始化 webView 的布尔条件 并在 webViewDidFinishLoad 中加载另一个委托 以便在完成完成后触发 但是 由于布尔值在条件 webViewDidFinishLoad 之前返回 因此页面永远不会完全加载 如何确
  • 使用 Push Transition 效果更改 RootViewcontroller

    在我的iOS应用程序中 我需要更改应用程序之间窗口的rootviewController 因此 当我动态更改我的rootviewcontroller时 它会在更改之前轻拂视图 但我想要的是在更改rootviewcontroller时提供平滑
  • 如何在我的 iOS 项目中添加和执行 .sql 文件?

    我找到了很多关于在 iOS 中使用 SQLite 数据库的教程 但没有找到任何直接引用 sql 文件的内容 谁能告诉我如何将现有的 SQL 数据库链接到我的应用程序 编辑 这是一个 MySQL 转储 我们有一个基于浏览器的抽认卡程序 现在我
  • M:N线程模型真的利用了CPU核心吗?

    有几种线程模型可用于在应用程序中调度线程 1 1 内核级线程 用户创建的每个线程都映射到内核中的调度线程 N 1 用户级线程 用户在单个应用程序中创建的所有线程实际上都映射到单个调度的内核线程 M N 混合螺纹 用户在应用程序中创建的 M
  • C# 线程和队列

    这不是关于我可以或应该使用的不同方法来以最佳方式利用队列 而是关于我所看到的对我来说毫无意义的事情 void Runner member variable queue Queue Synchronized new Queue while t
  • UIBezierPath 的起始和结束角度?

    我在 iOS 中使用如下代码编写了半圆UI贝塞尔路径 and CAShape层 clockWiseLayer CAShapeLayer alloc init CGFloat startAngle M PI 2 CGFloat endAngl
  • 使用反射的属性类型或类

    我想知道是否可以确定对象属性的类或原始类型 获取所有属性名称和值非常容易 所以答案 https stackoverflow com questions 2299841 objective c introspection reflection
  • 使用 volatile bool 强制另一个线程等待是否安全? (C++)

    我读到的有关 volatile 的所有内容都说它永远不安全 但我仍然倾向于尝试它 而且我还没有看到这种特定场景被宣布为不安全 我有一个单独的线程来渲染场景 从主模拟线程中提取数据 这没有同步 并且工作正常 问题是 当程序退出时 渲染器需要停
  • 优化 Keras 以使用所有可用的 CPU 资源

    好吧 我真的不知道我在说什么 所以请耐心听我说 我正在使用 Theano 后端运行 Keras 以在 MNIST 图像上运行基本的神经网络 目前只是一个教程 过去 我一直使用我的旧 HP 笔记本电脑 因为我有 Windows 和 Ubunt
  • 打印附加结构(swift 4)

    我有三个 textifled 用于将数据附加到结构中 如何打印我附加的内容 现在我收到一条错误消息 import UIKit class ViewController UIViewController IBOutlet var c UITe
  • “benaphores”值得在现代操作系统上实施吗?

    当我还是一名 BeOS 程序员时 我读过本文 http www haiku os org legacy docs benewsletter Issue1 26 html Engineering1 26作者 Benoit Schillings
  • 如何在ios中以编程方式添加水平间距和垂直间距?

    我在 ios 8 中创建了一个应用程序 因为我有 4 个可垂直使用的标签 它应该在某些条件下更改位置 所以我已禁用自动布局并以编程方式设置约束 现在的问题是 我可以设置水平和垂直位置 宽度和高度的约束 但我找不到任何方法来添加标签之间的水平
  • 具有多种自定义单元格类型的 RxSwift 表视图

    我想知道是否有任何代码示例RxSwift当我可以在一个表视图中使用多个自定义单元格时 例如 我有两个部分 第一部分有 10 个单元格 类型为CellWithImage标识符和第二部分有 10 个带有类型的单元格CellWithVideo标识
  • NSMenuItem、自定义视图和 mouseUp 的奇怪问题:

    我在这里遇到了一个非常非常奇怪的 NSMenu 问题 我使用的大约一半的 NSMenuItems 通过 NSMenuItem 上的 setView 方法具有自定义视图 在此自定义视图中 我实现了 mouseUp 来捕获用户单击菜单项的时间
  • 播放(非库)Apple Music 内容 - 请求失败

    我正在尝试使用以下代码播放专辑 let predicate MPMediaPropertyPredicate value 1459938538 forProperty MPMediaItemPropertyAlbumPersistentID
  • iOS 对 Google 云消息传递的支持

    我在谷歌的开发者控制台中看到 GCM 允许为 iOS 生成 API 密钥 我在网上搜索了有关如何在 iOS 应用程序中通过 GCM 实现推送通知的任何类型的文档 但没有找到答案 真的有可能在 iOS 应用程序中使用 GCM 实现推送通知 j
  • 通用类不会将委托调用转发给具体子类

    鉴于以下情况 protocol EntityType var displayString String get extension String EntityType var displayString String return self

随机推荐