Правильный шаблон для решения проблемы гонки с массивом BlockOperation (если он есть)
Взглянув на этот QA /questions/41234419/nsfetchedresultscontollerdelegate-dlya-collectionview/55282696#55282696,
Так,
var ops: [BlockOperation] = []
вызывается ОС один раз, чтобы сообщить нам, что мы начинаем:
func controllerWillChangeContent(..) {
possibly/IDK .. ops.removeAll()
}
Вызывается, скажем, 20 раз ОС:
func controller(..) {
ops.append(BlockOperation(block: { [weak self] in
self?.insertBlah(at: [blah!])
}))
}
}
вызывается один раз ОС, чтобы сообщить нам, что мы закончили, больше не будем:
func controllerDidChangeContent(_
controller: NSFetchedResultsController<NSFetchRequestResult>) {
performBatchUpdates({ () -> Void in
for op: BlockOperation in self.ops { op.start() }
}, completion: { (finished) -> Void in self.ops.removeAll() })
}
deinit {
for o in ops { o.cancel() }
ops.removeAll()
}
Вот в чем дело
Что, если начнут поступать новые элементы (т. Е. Вызывается controllerWillChangeContent, а затем вызывается контроллер несколько раз) ... фактически, пока выполняется performBatchUpdates?
в controllerDidChangeContent, стоит ли мне действительно сделать локальную копию ops, LC, - моментальный снимок на тот момент, - а затем стереть операции и выполнить пакетные обновления на LC? (Но! ... обратите внимание, что для этого, я думаю, вам наверняка придется заблокировать и каким-то образом выполнить эти два шага атомарно..???)
или моя голова задралась, и все, что указано в пункте 2, в любом случае выполняется с помощью performBatchUpdates?
заметьте, я опорожнить оп в завершении из выполнения. если пункт 3 верен, все неправильно. если пункт 2 верен, опять же все неправильно. И, возможно, это неправильно по какой-то другой причине!
обратите внимание, что некоторые предлагают очистить ops в предварительном вызове controllerWillChangeContent. но это кажется неправильным - IDK
если пункт 2 верен, действительно ли вам нужно складывать их вместе?! так что "операции" действительно должны быть стопкой "операций"! которые рассматриваются (каждая группа) по возможности?
или действительно все это заблуждение, и вам действительно нужно использовать какую-то очередь (FIFO) здесь?!! так что вы бы вообще ничего не делали в WillChange или DidChange, а просто ставили бы маленьких ублюдков в очередь и выполняли бы их FIFO. (Тогда вы бы даже использовали BlockOperation для такой вещи или это просто неправильно?)
Вот семь основных пунктов моего полного незнания:O
Коротко
- как справиться с возможностью того, что во время выступления может прибыть еще больше вещей;
- есть ли что-то большее, чем нужно сделать в этом шаблоне (очередь? локальная копия??);
- когда / как / когда-либо вы очищаете операции?