如何创建跨多个操作共享的实例变量
How to create an instance variable that is shared across multiple operations
我正在制作一个 UITableView,它显示根据处理后的数据创建的图像。
这个处理任务太重了,我决定声明一个数组类型的UITableView实例变量class,每个处理任务创建一个操作
因为每个结果都会存储到单独的内存中 space 由索引标识,我认为它是线程安全的。
一个简短的版本示例:
class TestOperation: Operation {
var pi: [Int?];
override var isExecuting: Bool { ... }
override var isFinished: Bool { ... }
init(_ p: inout [Int?]) {
pi = p;
}
override func start() {
if pi[0] == nil {
pi[0] = 0;
} else if pi[1] == nil {
pi[1] = 1;
} else {
pi[2] = 2;
}
}
}
class Root {
var sharedArr: [Int?];
var queue: OperationQueue;
init() {
sharedArr = Array(repeating: nil, count: 3);
queue = OperationQueue.init();
for _ in 0...2 {
let operation = TestOperation.init(&sharedArr);
queue.addOperation(operation);
}
}
}
Root.init();
我预计 sharedArr
会改变,但我得到的只是 nil 数组。有什么我可以尝试的吗?
swift 中的数组是结构,因此按值传递。我看到您将数组作为 inout 传递,所以您已经知道了。我遇到过几次这个问题,最后我作弊了。
作弊 1:将对 Root 的引用传递给 TestOperation,然后调用 Root 上的方法将值添加到共享数组。您可以使用协议使它更清洁。
作弊 2:创建一个 class 包装共享数组并具有更新包装数组的方法。
在这两种情况下,我都会将要使用的索引传递给 TestOperation,而不是从数组内容中推导出它。扣除可能取决于时间。
我知道这是在逃避而不是解决问题,但有时候人生太短暂
这是要点,未经测试:
protocol TestOperationProtocol: class {
function setValue(index: Int, value: Int)
}
class TestOperation: Operation {
weak var owner: TestOperationProtocol
let index: Int
override var isExecuting: Bool { ... }
override var isFinished: Bool { ... }
init(owner: TestOperationProtocol, index: Int) {
self.owner = owner
self.index = index
}
override func start() {
// calculate value
let value = self.index
self.owner?.setValue(self.index, value)
}
}
class Root: TestOperationProtocol {
var sharedArr: [Int?];
var queue: OperationQueue;
init() {
sharedArr = Array(repeating: nil, count: 3);
queue = OperationQueue.init();
for i in 0...sharedArr.count {
let operation = TestOperation.init(self, index: index);
queue.addOperation(operation);
}
}
func setValue(index: Int, value: Int) {
sharedArray[index] = value
}
}
该协议允许您打破依赖循环。 TestOperation 依赖于 TestOperationProtocol 而不是 Root。 Root 依赖于 TestOperation 及其协议。
我正在制作一个 UITableView,它显示根据处理后的数据创建的图像。
这个处理任务太重了,我决定声明一个数组类型的UITableView实例变量class,每个处理任务创建一个操作
因为每个结果都会存储到单独的内存中 space 由索引标识,我认为它是线程安全的。
一个简短的版本示例:
class TestOperation: Operation {
var pi: [Int?];
override var isExecuting: Bool { ... }
override var isFinished: Bool { ... }
init(_ p: inout [Int?]) {
pi = p;
}
override func start() {
if pi[0] == nil {
pi[0] = 0;
} else if pi[1] == nil {
pi[1] = 1;
} else {
pi[2] = 2;
}
}
}
class Root {
var sharedArr: [Int?];
var queue: OperationQueue;
init() {
sharedArr = Array(repeating: nil, count: 3);
queue = OperationQueue.init();
for _ in 0...2 {
let operation = TestOperation.init(&sharedArr);
queue.addOperation(operation);
}
}
}
Root.init();
我预计 sharedArr
会改变,但我得到的只是 nil 数组。有什么我可以尝试的吗?
swift 中的数组是结构,因此按值传递。我看到您将数组作为 inout 传递,所以您已经知道了。我遇到过几次这个问题,最后我作弊了。
作弊 1:将对 Root 的引用传递给 TestOperation,然后调用 Root 上的方法将值添加到共享数组。您可以使用协议使它更清洁。
作弊 2:创建一个 class 包装共享数组并具有更新包装数组的方法。
在这两种情况下,我都会将要使用的索引传递给 TestOperation,而不是从数组内容中推导出它。扣除可能取决于时间。
我知道这是在逃避而不是解决问题,但有时候人生太短暂
这是要点,未经测试:
protocol TestOperationProtocol: class {
function setValue(index: Int, value: Int)
}
class TestOperation: Operation {
weak var owner: TestOperationProtocol
let index: Int
override var isExecuting: Bool { ... }
override var isFinished: Bool { ... }
init(owner: TestOperationProtocol, index: Int) {
self.owner = owner
self.index = index
}
override func start() {
// calculate value
let value = self.index
self.owner?.setValue(self.index, value)
}
}
class Root: TestOperationProtocol {
var sharedArr: [Int?];
var queue: OperationQueue;
init() {
sharedArr = Array(repeating: nil, count: 3);
queue = OperationQueue.init();
for i in 0...sharedArr.count {
let operation = TestOperation.init(self, index: index);
queue.addOperation(operation);
}
}
func setValue(index: Int, value: Int) {
sharedArray[index] = value
}
}
该协议允许您打破依赖循环。 TestOperation 依赖于 TestOperationProtocol 而不是 Root。 Root 依赖于 TestOperation 及其协议。