gpt4 book ai didi

objective-c - 在 macOS 应用程序中,我有一个后台线程执行一行代码,需要花费大量时间。如何取消封禁?

转载 作者:行者123 更新时间:2023-12-03 16:53:41 28 4
gpt4 key购买 nike

在我正在开发的 Cocoa Objective-C 应用程序中,我有一个带有实现 tableViewSelectionDidChange 的委托(delegate)的 NSTableView。在该方法的委托(delegate)实现中,我放置了一个用 GCD 实现的后台串行队列,该队列负责加载表中当前选定的对象,以便将其显示在表右侧的详细 NSView 中。我期望的行为是,如果后台线程尚未完成并且左表中有一个新选择,我想取消它并为新选择启动一个新线程。我使用 GCD here 找到了一个非常优雅的解决方案使用:

dispatch_block_cancel(work);

问题是,就像链接中所说的那样:

“需要注意的一点是,dispatch_block_cancel 不是抢占式的。如果工作 block 正在长时间运行的操作中,dispatch_block_cancel 不会强制终止它。为此,我们必须定期测试使用dispatch_block_testcancel取消。这是一个例子:“

for (...) {
/* do some work */
[NSThread sleepForTimeInterval:0.2];

if (dispatch_block_testcancel(work) != 0) {
/* exit gracefully */
return;
}
}

问题是,在我的应用程序中,tableViewSelectionDidChange 实现中执行的最冗长的操作是在一行代码中,我无法重构我的代码来更改它,因为该语句正在调用我正在使用的外部 dylib。在这种情况下,我无法检查该 block 是否被取消:

if (dispatch_block_testcancel(work) != 0) {
/* exit gracefully */
return;
}

因为线程在冗长的单行操作上被阻塞。有人可以提出某种策略,最好仍然使用 GCD 吗?我知道 NSOperation 和 NSOperationQueue,但在学习使用它们之前,我想确定它们不会像 GCD 那样在 1 行语句中间取消操作时遇到问题。非常感谢您的帮助。

最佳答案

这是无法解决的。使用哪种工具(GCD 与 NSOperation)并不重要。无法强行停止正在进行的操作。它会使内存处于未知状态。解决方案是等待代码行完成,然后如果 block 被取消,则删除结果。如果该代码行的成本非常高,以至于您确实需要终止它(而不是仅仅忽略它的结果),那么您将必须用检查取消标志的代码替换该库。

关于objective-c - 在 macOS 应用程序中,我有一个后台线程执行一行代码,需要花费大量时间。如何取消封禁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54013959/

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