【问题标题】:Crashing at queue.sync { self._state }在 queue.sync { self._state } 处崩溃
【发布时间】:2023-07-04 15:52:01
【问题描述】:

我正在尝试创建 Operation 的异步子类。 代码在“状态”属性的 getter 上崩溃。 我找到了一篇解决异步子类的文章,但我很好奇为什么 queue.sync { self._state } 会发生崩溃 _state 属性的 willSet 和 DidSet 被调用,控件移动到它崩溃的 getter 状态 image of the crash

class ConcurrentOperation: Operation {
        private enum State: String {
            case ready = "isReady"
            case executing = "isExecuting"
            case finished = "isFinished"
        }
    
        private var _state: State = .ready {
            willSet {
                willChangeValue(forKey: newValue.rawValue)
                willChangeValue(forKey: _state.rawValue)
            }
            didSet {
                didChangeValue(forKey: _state.rawValue)
                didChangeValue(forKey: oldValue.rawValue)
            }
        }
    
        private let queue = DispatchQueue(label: "com.concurrentOperation.chanakkya",  attributes: .concurrent)
    
        private var state: State {
            get {
                queue.sync { self._state }
            }
            set {
                queue.sync(flags: .barrier) {
                    self._state = newValue
                }
            }
        }
    
        override var isReady: Bool {
            super.isReady && state == .ready
        }
    
        override var isExecuting: Bool {
            state == .executing
        }
    
        override var isFinished: Bool {
            state == .finished
        }
    
        override func start() {
            guard !isCancelled else {
                finish()
                return
            }
    
            if !isExecuting {
                state = .executing
            }
    
            main()
        }
    
        override func main() {
            fatalError()
        }
    
        func finish() {
            if isExecuting {
                state = .finished
            }
        }
    
        override func cancel() {
            super.cancel()
            finish()
        }
    
    }

【问题讨论】:

    标签: ios nsoperationqueue nsoperation


    【解决方案1】:

    你必须使用临时变量

    private var state: State {
                get {
                    var temp: State!
                    queue.sync { 
                       temp  = self._state 
                    }
                    return temp
                }
                set {
                    queue.sync(flags: .barrier) {
                        self._state = newValue
                    }
                }
            }
    

    【讨论】:

    • 它仍然崩溃。我认为崩溃可能与操作生命周期、被调用的 KVO 或其他原因有关