Я хотел иметь отменяемые блоки, которые мои UICollectionViewController
могли бы легко отменить, когда ячейки прокручивались за пределы экрана.Блоки не выполняют сетевые операции, они выполняют операции с изображениями (изменение размера, обрезка и т. Д.).Сами блоки должны иметь ссылку, чтобы проверить, была ли отменена их операция, и ни один из других ответов (на момент написания этой статьи) не предусматривал этого.
Вот что сработало для меня (Swift 3) -делая блоки, которые принимают слабый реф в BlockOperation
, затем оборачивая их в сам блок 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
}
}
Используя его в моем 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()
}
}
Завершение картины:
class Weak<T: AnyObject> {
weak var value : T?
init (value: T) {
self.value = value
}
}