Программно Init против dequeueForReusableIdentifier для ячеек табличного представления - PullRequest
0 голосов
/ 30 января 2019

Я разрабатываю приложение с использованием построителя интерфейса и создал несколько ячеек, которые получают viewModel для него init:

class ExampleCell {
    var anInternalView: ExampleView
    var anotherInternalView: ExampleView

    init(viewModel: ExampleViewModel) {
         anInternalView = ExampleView(viewModel: viewModel)
         anotherInternalView = ExampleView(viewModel: viewModel)
         ...
    }
    ...
}

В моем tableViewCellForRowAt просто создаем экземпляры ячеек, используя ExampleView (viewModel: viewModel),

Некоторые говорят, что это не так хорошо, и что я должен использовать dequeuForReusableIdentifier.Но на самом деле этот метод также вызывает init столько раз, сколько напрямую использует пользовательский конструктор.Кроме того, я не могу передать viewModel в init.

Я не нашел так много материала, объясняющего, почему использование dequeueForReusableIdentifier так лучше.Может кто-нибудь указать мне причину этого?

Ответы [ 2 ]

0 голосов
/ 30 января 2019

(расширение правильного ответа @rmaddy)

Вкратце, init() потребляет память, а dequeueReusableCell(withIdentifier:for:) - обработку.Естественно, мы предпочитаем добавить немного больше времени выполнения, чем исчерпать немного доступной памяти.

На мой взгляд, использование init не является неправильным при использовании только нескольких ячеек, поскольку проблема с dequeueReusableCell это повторное использование.Я имею в виду, что если вам нужна новая ячейка при прокрутке, то tableView назначит ячейку с предварительно заданной настройкой с другой конфигурацией, и нам нужно сбросить (или перенастроить) ее.Так что было бы неплохо иметь несколько неизменных экземпляров клетки.Но, с другой стороны, будет больше здоровых до deque, когда мы не знаем, сколько строк будет иметь наш tableView.

0 голосов
/ 30 января 2019

Вы не хотите передавать модель методу init.Клетки снова и снова используются для разных рядов.Вам необходимо установить модель в cellForRowAt после создания ячейки.

Вместо вашего init, добавьте метод applyModel (или похожее имя):

class ExampleCell {
    var anInternalView: ExampleView
    var anotherInternalView: ExampleView

    apply(viewModel: ExampleViewModel) {
         anInternalView = ExampleView(viewModel: viewModel)
         anotherInternalView = ExampleView(viewModel: viewModel)
         ...
    }
    ...
}

Тогда в вашем cellForRowAt:

let cell = tableView.dequeueReusableCell(withIdentifier: "Some ID", for: indexPath) as! ExampleCell
cell.apply(viewModel: someModelForIndexPath)

Ключевым моментом, который следует помнить, является то, что init будет вызываться только небольшое количество раз.Если, например, ваше табличное представление может отображать только 6 ячеек в любой момент времени на экране, то будут созданы только шесть (может быть, семь) ячеек, даже если в табличном представлении есть тысячи строк.Так что init будет вызываться только 6 (или 7) раз, тогда как cellForRowAtapply) может вызываться много тысяч раз, когда пользователь прокручивает все строки назад и вперед.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...