LNZWeakCollection 1.3.2

LNZWeakCollection 1.3.2

测试已测试
Lang语言 SwiftSwift
授权 MIT
Released最新发布2019 年 5 月
SPM支持 SPM

Giuseppe Lanza 维护。



  • Giuseppe Lanza

LNZWeakCollection

代理模式是一种常用的在对象之间传递消息和值的模式。

我们都知道这种模式的潜在问题

  • 代理对象必须拥有一个弱引用以避免保留循环。
  • 代理对象必须确保代理符合代理协议,否则可能会导致由于不识别选择器而崩溃。

如果期望的行为是让更多对象监听回调,并且您打算使用代理模式来处理多个代理,您可能会这样做

class MyProxy: NSObject, UITableViewDelegate {
    weak var delegate1: UITableViewDelegate?
    weak var delegate2: UITableViewDelegate?

    public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        delegate1?.tableView?(tableView, didSelectRowAt: indexPath)
        delegate2?.tableView?(tableView, didSelectRowAt: indexPath)
    }
}

这种方法当然可以工作。但这非常不灵活。您只能有 2 个代理,并且显然如果您想添加更多,您必须添加 delegate3 var,记得更新所有方法等等。

这个问题的解决方案是什么?我们希望更加灵活,以避免大量的猴子工作。我们不能使用数组,因为它们会导致对象保留最终导致保留循环,而且我们也不能用 NSHashTable 和 NSMapTable,因为它们的零化行为并不总是符合预期。特别是NSMapTable 保留对象,直到数据结构需要调整大小。这意味着不清楚,但结论是,如果您想要释放弱引用,它们是不可靠的。

LNZWeakCollection 包含一个弱引用集合(WeakCollection)和一个具有弱键或弱值(WeakDictionary)的字典。

使用 WeakCollection,您将能够这样做

public class TableViewDelegateProxy: NSObject, UITableViewDelegate {
    var delegates = WeakCollection<UITableViewDelegate>()
	
    public func addDelegate(object: UITableViewDelegate) {
        delegates.add(object: object)
    }
	
    public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        delegates.execute { (delegate) in
            delegate.tableView?(tableView, didSelectRowAt: indexPath)
        }
    }
}

Weak collection 遵循 Sequence 协议,因此您可以通过对象迭代

    var delegates = WeakCollection<UITableViewDelegate>()

    for (i, delegate) in delegates.enumerated() {
        delegate.tableView?(tableView, didSelectRowAt: indexPath)
    }
    
    for delegate in delegates {
        delegate.tableView?(tableView, didSelectRowAt: indexPath)
    }

要安装它,您可以将 swift 文件拖放到项目中,或者通过 Cocoapod 进行安装

    pod 'LNZWeakCollection'