gpt4 book ai didi

ios - 如何从 NSOperations 收集数据到数组中?

转载 作者:行者123 更新时间:2023-11-29 01:23:10 24 4
gpt4 key购买 nike

我有一些 NSOperations异步创建一些数据。我想将所有结果收集到一个数组中。因为我在多个不同的线程上访问数组,所以我在数组周围加了锁。

NSOperationQueue正在将数据附加到数组,但结果似乎遗漏了一些数据对象。每次运行时结果似乎都不同。

我创建了一个简化的示例项目来重现该问题。代码是用 Swift 编写的,但我认为这不是特定于 Swift 的。

import UIKit

class ViewController: UIViewController {
let queue = NSOperationQueue()
var bucket = [String]()

override func viewDidLoad() {
super.viewDidLoad()

queue.addObserver(self, forKeyPath: "operations", options: NSKeyValueObservingOptions.New, context: nil)

for _ in 0..<10 {
queue.addOperation(NSBlockOperation {
// Let's pretend that creating the "fish" string is actually potentially
// expensive and that's why we're doing it in an NSOperation.
let fish = "fish"

objc_sync_enter(self.bucket)
self.bucket.append(fish)

let fishCount = self.bucket.count
print("Bucket contains \(fishCount) fish" + ((fishCount != 1) ? "es" : ""))
objc_sync_exit(self.bucket)
})
}
}

override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
if let keyPath = keyPath {
if let object = object as? NSOperationQueue {
if object == queue && keyPath == "operations" {
if queue.operationCount == 0 {
objc_sync_enter(self.bucket)
let fishCount = bucket.count
print("Bucket finally contains \(fishCount) fish" + ((fishCount != 1) ? "es" : ""))
objc_sync_exit(self.bucket)
}
} else {
super.observeValueForKeyPath(keyPath, ofObject: object, change: change, context: context)
}
}
}
}
}

结果各不相同,但通常是这样的:

Bucket contains 1 fish
Bucket contains 1 fish
Bucket contains 1 fish
Bucket contains 1 fish
Bucket contains 2 fishes
Bucket contains 1 fish
Bucket contains 1 fish
Bucket contains 3 fishes

此外,有时代码会因 EXC_BAD_ACCESS 而崩溃。在线self.bucket.append(fish)

此外,行 print("Bucket finally contains \(fishCount) fish" + ((fishCount != 1) ? "es" : ""))observeValueForKeyPath永远不会被调用。我不确定这是否是一个单独的问题。

最佳答案

你应该看看子类化 NSOperation ,因为它是一个抽象类。看这个Stackoverflow question用于子类化。考虑到这一点,我建议您在每个操作实例上都有一个标识符属性,以便您可以跟踪您的操作,这样您就可以知道您的所有操作何时完成。您也可以考虑将这段代码从您的 View Controller 类中拉出并创建一个类来处理您的鱼另外,当您不再对鱼感兴趣但对猫感兴趣时,它会帮助您进一步封装 :)

The Concurrency Programming Guide非常擅长解释异步应用程序设计的基础知识。

The NSOperation class is an abstract class you use to encapsulate the code and data associated with a single task. Because it is abstract, you do not use this class directly but instead subclass or use one of the system-defined subclasses (NSInvocationOperation or NSBlockOperation) to perform the actual task. Despite being abstract, the base implementation of NSOperation does include significant logic to coordinate the safe execution of your task. The presence of this built-in logic allows you to focus on the actual implementation of your task, rather than on the glue code needed to ensure it works correctly with other system objects.

关于ios - 如何从 NSOperations 收集数据到数组中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34356277/

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