Правильный шаблон для решения проблемы гонки с массивом BlockOperation (если он есть) - PullRequest
0 голосов
/ 04 февраля 2020

Взглянув на это QA { ссылка },

Итак,

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()
}

Вот в чем дело

  • Что, если новые элементы начнут поступать (ie, вызывается controllerWillChangeContent, а затем вызывается контроллер несколько раз) ... на самом деле во время выполнения executeBatchUpdates ?

  • в controllerDidChangeContent, если я действительно сделаю локальную копию операций, L C, - снимок в этот момент - , а затем стереть ops , а пакетное обновление на L C? (Но! ... обратите внимание, что для этого, я думаю, вам наверняка придется заблокировать и как-то выполнить эти два шага атомарно .. ???)

  • или моя голова в заднице, и все, что в пункте 2, сделано в любом случае с помощью executeBatchUpdates?

  • обратите внимание, я пуст операций в завершение выполнить . если пункт 3 верен, это все неправильно. если пункт 2 правильный, опять же, это все неправильно. И, возможно, это неправильно по какой-то другой причине!

  • обратите внимание, что некоторые предлагают очистить out ops, при предварительном вызове controllerWillChangeContent. но это кажется неправильным - ИДК

  • если точка 2 верна, на самом деле вам действительно нужно составлять эти вверх ?! таким образом, "ops" должен действительно быть стеком"ops"! которые рассматриваются (каждая группа из них), насколько это возможно?

  • или действительно все неправильно введено и вам действительно нужно использовать (FIFO) какая-то очередь здесь? !! так что вы вообще ничего не сделаете в WillChange или DidChange, и вы просто поставите в очередь маленьких ублюдков и сделаете их FIFO. (Тогда, вы бы даже использовали BlockOperation для такой вещи или все просто неправильно?)

Вот мои семь основных моментов полного отсутствия знаний: O

Короче говоря

  • как справиться с возможностью того, что во время исполнения вы можете получить больше материала;
  • - это больше, чем нужно сделать в этом паттерне ( очередь ?? локальная копия ??);
  • когда / как / когда вы очищаете ops?
...