I wanted to have undo blocks that my UICollectionViewController could easily undo when cells were scrolled from the screen. Blocks do not perform network operations, they perform operations with images (resizing, cropping, etc.). The blocks themselves should have a link to check if their op has been canceled, and none of the other answers (at the time I wrote this) provided that.
Here, what worked for me (Swift 3) is creating blocks that take a weak link to BlockOperation , and then complete them in the BlockOperation block BlockOperation :
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<BlockOperation>]() 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() } }
Image completion:
class Weak<T: AnyObject> { weak var value : T? init (value: T) { self.value = value } }
xaphod Jun 29 '17 at 6:29 2017-06-29 06:29
source share