自定义委托和数据源NSObjects最佳实践

时间:2019-03-24 14:13:26

标签: ios swift memory-management

所以考虑这种情况,我有一个text,其中包含一个简单的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

2 个答案:

答案 0 :(得分:1)

您的问题相当模糊,但总的来说,这是非常普遍的做法。我们在公司中经常使用这种模式:

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 = ...
    }
}

关于内存泄漏,这种模式通常是安全的,但显然有人偶尔会遇到内存问题。您的里程可能会有所不同。

答案 1 :(得分:1)

这种方法将来会导致任何内存泄漏吗?

现在不行。
您的内存图将如下所示: memory graph

因此,这里没有内存循环,也没有泄漏内存的原因。

重要。如果您在viewController上从DataSource / Delegate添加引用,请确保它是弱引用,否则将创建内存周期。

注意。您可以在collectionView的DataSource / Delegate中添加强引用,因为collectionView在dataSource和委托上具有弱引用。所以也没有周期

旁注

最好在数据源中注册单元格,因为“只有”数据源知道将使用哪种类型的单元格。