如何创建跨多个操作共享的实例变量

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 及其协议。