代码之家  ›  专栏  ›  技术社区  ›  Mohmmad S

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

  •  2
  • Mohmmad S  · 技术社区  · 7 年前

    所以考虑这个案子,我有一个 UIViewController 包含一个简单的 UICollectionView ,但是 Delegate & DataSource 协议是分开的 NSObject 来自 uiview控制器 是的。

    看起来像这样

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

    我把它们放在 uiview控制器 这样地,

    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

    1 回复  |  直到 7 年前
        1
  •  1
  •   ManWithBear    7 年前

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

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

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

    重要的 是的。如果在viewcontroller上添加来自datasource/delegate的引用,请确保它是弱引用,否则将创建内存循环。

    注意 是的。您可以在collectionview上从datasource/delegate添加强引用,因为collectionview在datasource和delegate上有弱引用。所以也没有周期

    旁注

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

        2
  •  1
  •   Mike Henderson    7 年前

    你的问题相当含糊,但总的来说,这是一种很常见的做法。我们公司经常采用这种模式:

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

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