2016-09-16 76 views
2

在调用dismissViewControll之后,我一直使用协议和委托方法将数据传递回前一个VC。下面就是我通常会做,因为它是不是这样,大多数教程编写弱代理和类协议

protocol someVCDelegate { 
    func somefunction() 
} 

var delegate: someVCDelegate! 

不过,我碰到写它的这个类/弱的办法。

protocol someVCDelegate : class { 
    func somefunction() 
} 

weak var delegate: someVCDelegate! 

我明白,弱与ARC相关联,并避免保留周期。但是,我不知道什么时候我需要它,因为在我所有的情况下,没有做弱代理作品发现(VC确实不行)。在什么情况下我需要弱代表?另外,它为什么是“!”弱后,通常是“?”后弱了吧?

+0

你是否在任何时候让代表零?或者前一个VC不保留对下一个VC的引用?我怀疑为什么在VC上调用deinit,如果一个对象至少有一个强引用它,ARC不会清理它。因此,如果前面的VC引用了下一个VC,并且下一个VC具有对之前的(强)委托引用,那么ARC将不会删除它们,如果它们失去所有其他引用导致内存泄漏 – Fonix

+0

它始终是一种很好的做法,无论如何,它并不困难,并且可以为您节省一些未来的麻烦。可能难以调试,如果它稍后成为问题 – Fonix

+0

今天刚刚阅读。它为我澄清了一些疏忽:ARC。 https://www.raywenderlich.com/134411/arc-memory-management-swift – Adrian

回答

2

你说:

但是,我不知道,当我需要它在我所有的情况下,不这样做弱的代表作品

你只需要微弱的协议,委托模式当你有一个强大的参考周期的潜力,即一系列强大的参考循环。例如,考虑:

  • 具有属性(“子”)的对象(“父”),即父对子具有强引用;

  • 孩子有delegate财产;和

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

在这种情况下,它的关键,该委托是weak引用,否则你就会有很强的参考周期。

请注意,这是一个微不足道的例子,有时强引用链可能相当复杂。例如,考虑具有委托属性的UIView子类。从视图控制器到其根目录view,通过子视图的一系列子视图,一直到UIViewdelegate,潜在的强参考周期可能是相当长的,可能会引用回视图控制器。这也将导致强烈的参考周期,因此我们倾向于使用delegateweak参考。

但是,当您使用协议委托模式在视图控制器之间传递数据时,这通常不是问题(视图控制器遏制除外),因为呈现视图控制器不拥有呈现的视图控制器。视图控制器层次通常保持对视图控制器的强引用。所以,当你关闭所提供的视图控制器时,它将被解除分配,并且可能的强参考周期得到解决。

通常,我们会本能地采用weak协议委托模式(仅仅因为它阻止了强参考周期的发生)。但有时你会使用强大的参考。最常见的强参考模式是NSURLSession,其delegate是一个有力的参考。由于documentation for init(configuration:delegate:delegateQueue:)警告我们:

会话对象保持较强的参考delegate,直到你的应用程序退出或明确的会话无效。如果您不通过调用invalidateAndCancel()finishTasksAndInvalidate()方法使会话失效,则应用程序会泄漏内存直到退出。

虽然这看起来似是而非,这种强烈的参考模式的优点是会话知道它可以安全地调用其委托的方法,而不必担心其被释放的对象。 (顺便说一下,NSURLSession这个强大的代表行为很少会出现丑陋的头部,因为我们经常使用完成处理程序方法,根本不使用委托方法,而且当我们使用委托方法时,我们经常会有其他对象而不是视图控制器作为会话的代表)。

总之,您真的必须评估每种情况,并确定我们本能地倾向于的弱引用是否更好,或者您是否有其中一种情况协议最好配合强大的参考。

0

为什么它很弱:弱引用是一个引用,它不会强制保留它引用的实例,因此不会停止ARC处置引用的实例。此行为可防止参考成为强参考周期的一部分。或者简单地说,通过将类之间的某些关系定义为弱引用或无主引用而不是强引用来解决强引用周期。

它是“!”因为它被隐式地解开,所以很弱。它会有一个价值。

有时从程序的结构中可以清楚地看到,在第一次设置值之后,可选项将始终有一个值。在这些情况下,每次访问时都不必检查和打开可选的值,因为可以安全地假定所有时间都有值。