gpt4 book ai didi

multithreading - 观察后台任务进度的 Cocoa 方式是什么?

转载 作者:行者123 更新时间:2023-12-03 16:05:30 25 4
gpt4 key购买 nike

想象一下以下情况:您有一个后台任务(这里的术语“任务”是指随机计算单元,而不是 NSTask!),它是使用任何现代技术(例如 Grand Central Dispatch 或操作队列)实现的。主线程上的某些 Controller 对象想要监视此后台任务的进度并将其报告给用户。

任务进度可以具有以下特征:

  • 不确定或确定
    因为 Controller 对象必须知道何时将 NSProgressIndicator 切换到适当的样式。我们可以使用一个约定,即在实际进度值从零上升之前,进度被视为不确定。
  • 进度值本身
    一个简单的浮点值
  • 当前阶段的本地化描述
    NSString,因为与用户的沟通很好

什么设计最适合这些要求,同时又最像 Cocoa 风格?

可能有变体。

委托(delegate)

在启动任务之前,将 Controller 对象设置为委托(delegate)。

@protocol MyBackgroundTaskDelegate
@required
- (void) progress: (float) value; // 0.0…1.0
@optional
- (void) workingOn: (NSString*) msg; // @"Doing this, doing that…"
@end

其实这个模板我已经成功使用过很多次了,但是感觉有点太冗长了。

阻止回调

与委托(delegate)非常相似,但将代码保留在一处。

// Starting our background task...
[MyTask startComputationWithProgressHandler: ^(float progress, NSString* msg)
{
// Switching to the main thread because all UI stuff should go there...
dispatch_async(dispatch_get_main_queue(), ^()
{
self.progressIndicator.progress = progress;
self.informationalMessage = msg;
});
}];

KVO 或进度属性轮询

在这种情况下,后台任务对象必须具有与以下类似的两个属性:

@property(readonly, atomic) float progress;
@property(readonly, atomic) NSString* message;

客户端(我们的 Controller 对象)应该将自己设置为这些属性的观察者。我在此解决方案中看到的主要缺陷是 KVO 通知始终到达导致更改的同一线程。虽然您可以强制观察者(回调)方法在特定的 GCD 队列上运行,但它可能并不总是合适。

NS通知中心

后台任务发送通知,客户端监听它们。

还有其他适用于这种情况的模式吗?什么解决方案可以被视为最现代、最接近 Cocoa 的解决方案?

最佳答案

说到观察后台任务进度的Cocoa方式是什么?我会说委托(delegate)和NSNotificationCenter,因为 block 和KVO是后来引入的,因此最初并不存在于第一个 Cocoa 代码编写年代。事实上,可选的协议(protocol)方法在以前的 objc 版本中也不存在,默认情况下一切都是必需的。

从中您实际上可以看到 block 是实现临时委托(delegate)的一种更简单的方法,其中 block 的接收者声明将哪些参数传递给 block ,并且您可以在 中自由地对它们执行任何操作你的 block 。 KVO 似乎是一种使用更标准化的属性方法来实现 NSNotification 的样板代码较少的方法,对于加入在之前称为 Interface Bilder 中创建的 UI 非常有用,并简化了“什么是我必须做什么才能知道这个值何时发生变化” 这需要大量带有 NSNotification 和长常量的文档。

但我仍然认为这些技术都有各自的用武之地: block 对于迷你自组织协议(protocol)来说很好,但是如果您需要中等或更高的接口(interface)区域或双向接口(interface),而 KVO 不需要,那么这将是一个严重的麻烦帮助监视类/对象之外的全局变量或值,或者您不想成为公共(public)接口(interface)一部分的内容。

所以我的明确答案是:

  • 一对一的简单沟通:区 block
  • 一对一的复杂通信:委托(delegate)/协议(protocol)
  • 一对多简单通信:KVO(如果可能)
  • 一对多复杂通信:NSNotifications

一如既往,为每个问题选择最好的工具,并考虑到我没有以任何建议的方式实现上述所有内容!

关于multithreading - 观察后台任务进度的 Cocoa 方式是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12403229/

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