How to cancel NSBlockOperation

后端 未结 4 983
粉色の甜心
粉色の甜心 2020-11-30 22:28

I have a long running loop I want to run in the background with an NSOperation. I\'d like to use a block:

NSBlockOperation *operation = [NSBlock         


        
4条回答
  •  情歌与酒
    2020-11-30 23:00

    I wanted to have cancellable blocks that my UICollectionViewController could easily cancel once cells were scrolled off the screen. The blocks are not doing network ops, they are doing image operations (resizing, cropping etc). The blocks themselves need to have a reference to check if their op has been cancelled, and none of the other answers (at the time I wrote this) provided that.

    Here's what worked for me (Swift 3) - making blocks that take a weak ref to the BlockOperation, then wrapping them in the BlockOperation block itself:

        public extension OperationQueue {
            func addCancellableBlock(_ block: @escaping (BlockOperation?)->Void) -> BlockOperation {
                let op = BlockOperation.init()
                weak var opWeak = op
                op.addExecutionBlock {
                    block(opWeak)
                }
                self.addOperation(op)
                return op
            }
        }
    

    Using it in my UICollectionViewController:

    var ops = [IndexPath:Weak]()
    
        func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
            ...
            ops[indexPath] = Weak(value: DispatchQueues.concurrentQueue.addCancellableBlock({ (op) in
                cell.setup(obj: photoObj, cellsize: cellsize)
            }))
        }
    
        func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
            if let weakOp = ops[indexPath], let op: BlockOperation = weakOp.value {
                NSLog("GCV: CANCELLING OP FOR INDEXPATH \(indexPath)")
                op.cancel()
            }
        }
    

    Completing the picture:

        class Weak {
            weak var value : T?
            init (value: T) {
                self.value = value
            }
        }
    

提交回复
热议问题