Передовая практика пользовательских делегатов и источников данных NSObjects - PullRequest
3 голосов
/ 24 марта 2019

Итак, рассмотрим этот случай, у меня есть UIViewController, который содержит простой UICollectionView, но Delegate & DataSource протоколы отделены NSObject от UIViewController.

Это выглядит примерно так

class MainCollctionViewDelegate: NSObject, UICollectionViewDelegate
class MainCollectionViewDataSrouce: NSObject, UICollectionViewDataSource

И я использую их внутри моего UIViewController вот так

lazy var CVDelegate = MainCollctionViewDelegate()
lazy var CVDataSource = MainCollectionViewDataSrouce()
//MARK: - Life Cycle
override func viewDidLoad() {
    super.viewDidLoad()
    collectionView.registerCell(PlainCell.self) // register custom cell Nib into collection View.
    collectionView.delegate = CVDelegate //Set Deleagte
    collectionView.dataSource = CVDataSource // Set data Source
}

Будет ли такой подход вызывать любые утечки памятив будущем ?учитывая, что я буду внедрять инъекцию, чтобы заполнить источник данных CollectionView, чтобы это было что-то подобное в будущем.

 MainCollectionViewDataSrouce(with: Foo) // Foo is some data to populate the collection with. 

Есть ли лучшая практика для этого?учитывая, что я пытаюсь добиться минимального написания кода (избыточность).

Примечание: это также относится к UITableViewDelegate & UITableViewDataSource

Ответы [ 2 ]

1 голос
/ 24 марта 2019

Не вызовет ли этот подход утечки памяти в будущем?

Не сейчас.
Ваш график памяти будет выглядеть следующим образом: memory graph

Так что здесь нет циклов памяти и нет причин для утечки памяти.

Важно .Если вы добавляете ссылку из DataSource / Delegate на свой viewController, убедитесь, что это слабая ссылка, иначе вы создадите цикл памяти.

Примечание .Вы можете добавить сильные ссылки из DataSource / Delegate на collectionView, так как collectionView имеет слабые ссылки на dataSource и делегат.Таким образом, цикл также отсутствует

Примечание

Лучше регистрировать ячейки в источнике данных, поскольку «единственный» источник данных знает, какие типы ячеек будут использоваться.

1 голос
/ 24 марта 2019

Ваш вопрос довольно расплывчатый, но в целом это очень распространенная практика. Мы часто используем эту модель в нашей компании:

class MainCollectionViewController: UIViewController {
    lazy var dataSource: UICollectionViewDataSource = self
    lazy var delegate: UICollectionViewDelegate = self

    static func with(dataSource: UICollectionViewDataSource, delegate: UICollectionViewDelegate) -> MainCollectionViewController {
        let vc = MainCollectionViewController()
        vc.dataSource = dataSource
        vc.delegate = delegate

        return vc
    }
}

extension MainCollectionViewController: UICollectionViewDataSource {
    // code
}

extension MainCollectionViewController: UICollectionViewDelegate {
    // code
}

Два основных способа использования - для модульного тестирования и для передачи данных в контроллер представления. Тестер может внедрить пользовательский источник данных и делегировать его во время теста:

let testVC = MainCollectionViewController.with(dataSource: ..., delegate: ...)
// do test

Или передать ему данные:

// In another view controller
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if let destinationVC = segue.destination as? MainCollectionViewController {
        destinationVC.dataSource = ...
        destinationVC.delegate = ...
    }
}

Что касается утечки памяти, этот шаблон в целом безопасен, но, очевидно, кто-то время от времени сталкивается с проблемой памяти. Ваш пробег может отличаться.

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