弱代表和类协议

时间:2016-09-16 01:56:04

标签: ios swift delegates protocols swift-protocols

我一直在使用protocol和delegate方法在调用dismissViewControll之后将数据传回给前一个VC。以下是我通常会这样做的原因,因为大多数教程都不是这样写的

protocol someVCDelegate {
    func somefunction()
}

var delegate: someVCDelegate!

但是,我遇到了写这种类/弱方法。

protocol someVCDelegate : class {
    func somefunction()
}

weak var delegate: someVCDelegate!

我知道弱与ARC相关并避免保留周期。但是,我不确定何时需要它,因为在我的所有情况下,没有做弱代理工作查找(VC确实deinit)。在什么样的情况下我需要弱代表?另外,为什么呢?"!"在弱势之后,通常是"?"在弱者之后?

2 个答案:

答案 0 :(得分:3)

你说:

  

但是,我不确定何时需要它,就像我的所有情况一样,不做弱委托工作

当您有可能进行强参考周期时,您只需要弱协议委托模式,即一系列强引用循环。例如,考虑:

  • 一个具有属性的对象(" parent")(" child"),即父对象具有强引用;

  • 孩子有delegate财产;和

  • 您将孩子的delegate设置为引用父对象。

在这种情况下,代表是weak引用至关重要,否则您将有一个强大的参考周期。

注意,这是一个简单的例子,有时强引用链可能相当复杂。例如,考虑具有委托属性的UIView子类。潜在的强引用周期可能很长,从视图控制器到其根view,通过子视图的一系列子视图,一直到UIViewdelegate,可能会引用回视图控制器。这也将导致强大的参考周期,并且由于这个原因,我们倾向于对weak使用delegate引用。

但是,当您使用协议委托模式在视图控制器之间传递数据时,这通常不是问题(视图控制器包含除外),因为呈现视图控制器不拥有所呈现的查看控制器。视图控制器层次结构通常维护对视图控制器的强引用。因此,当您关闭所呈现的视图控制器时,它将被解除分配,并且可以解决潜在的强参考周期。

通常,我们会本能地使用weak协议委托模式(仅仅因为它可以防止强引用循环发生)。但有时您会使用强引用。最常见的强参考模式是NSURLSessiondelegate是强引用。正如documentation for init(configuration:delegate:delegateQueue:)警告我们:

  

会话对象保留对delegate的强引用,直到您的应用退出或明确使会话无效为止。如果您没有通过调用invalidateAndCancel()finishTasksAndInvalidate()方法使会话无效,那么您的应用会在内存泄漏之前泄漏内存。

虽然这可能看似矛盾,但这种强大的参考模式的优点是会话知道它可以安全地调用其委托方法而不必担心对象已被解除分配。 (顺便说一下,NSURLSession的这种强大的委托行为很少会让人头疼,因为我们经常使用完成处理程序方法,并且根本不使用委托方法,当我们使用委托方法时,除了视图控制器之外,我们经常会有一些对象作为会话的委托。)

简而言之,你真的必须评估每种情况,并确定我们本能地倾向于弱的参考是否更好,或者你是否有其中一种情况,你的协议更好地服务于强引用。

答案 1 :(得分:0)

为什么它很弱:弱引用是一个引用,它不会强制保持它引用的实例,因此不会阻止ARC处理引用的实例。此行为会阻止引用成为强引用循环的一部分。或者简单地说,您通过将类之间的某些关系定义为弱引用或无引用引用而不是强引用来解析强引用循环。

它是“!”在弱之后因为它被隐含地打开了。它会有价值。

有时从程序的结构可以清楚地看出,在首次设置该值之后,可选项将始终具有值。在这些情况下,每次访问时都不需要检查和解包可选的值,因为可以安全地假设它始终具有值。