简体   繁体   English

弱代表和类协议

[英]weak Delegate and class protocol

I have been using protocol and delegate method to pass data back to the previous VC after dismissViewControll is called. 在调用dismissViewControll之后,我一直在使用protocol和delegate方法将数据传回给前一个VC。 Below is how I would normally do it as it is not way that most tutorial was written 以下是我通常会这样做的原因,因为大多数教程都不是这样写的

protocol someVCDelegate {
    func somefunction()
}

var delegate: someVCDelegate!

However, I came across this class/weak approach of writing it. 但是,我遇到了写这种类/弱方法。

protocol someVCDelegate : class {
    func somefunction()
}

weak var delegate: someVCDelegate!

I understand that weak is associated to ARC and avoiding retain cycle. 我知道弱与ARC有关并且避免了保留周期。 However, I am not sure when I would need it as in all my cases, not doing weak delegate works find (VC does deinit). 但是,我不确定何时需要它,因为在我的所有情况下,没有做弱代理工作查找(VC确实deinit)。 In what sort of situation would I need weak delegate? 在什么样的情况下我需要弱代表? Also, why is it "!" 另外,为什么它是“!” after weak, normally it is "?" 弱,通常是“?” after weak right? 弱者之后?

You say: 你说:

However, I am not sure when I would need it as in all my cases, not doing weak delegate works 但是,我不确定在所有情况下我什么时候都需要它,而不是做弱委托工作

You only need the weak protocol-delegate pattern when you have a potential for a strong reference cycle, ie a circular series of strong references. 当您有可能进行强参考循环时,您只需要弱的协议委托模式,即一系列强引用循环。 For example, consider: 例如,考虑:

  • an object (the "parent") that has a property (the "child"), ie the parent has a strong reference to the child; 具有属性(“子”)的对象(“父”),即父对子具有强引用;

  • the child has a delegate property; 孩子有delegate财产; and

  • you set the child's delegate to refer to the parent object. 您将子delegate设置为引用父对象。

In that case, it's critical that the delegate be weak reference or else you'll have a strong reference cycle. 在这种情况下,代表是weak引用至关重要,否则你将有一个强大的参考周期。

Note, this is a trivial example and sometimes the chain of strong references can be rather complicated. 注意,这是一个简单的例子,有时强引用链可能相当复杂。 For example, consider a UIView subclass that has a delegate property. 例如,考虑具有委托属性的UIView子类。 The potential strong reference cycle can be quite long, from the view controller to its root view , through a series of subviews of subviews, all the way down to the UIView with the delegate that might potentially reference back to the view controller. 潜在的强引用周期可能很长,从视图控制器到其根view ,通过子视图的一系列子视图,一直到具有可能可能引用回视图控制器的delegateUIView That will result in a strong reference cycle, too, and we'd be inclined to use a weak reference for that delegate for that reason. 这也将导致强大的参考周期,并且由于这个原因,我们倾向于为该delegate使用weak引用。

But when you employ protocol-delegate pattern for passing data between view controllers, though, this generally isn't a problem (with the exception of view controller containment) because the presenting view controller doesn't own the presented view controller. 但是,当您使用协议委托模式在视图控制器之间传递数据时,这通常不是问题(视图控制器包含除外),因为呈现视图控制器不拥有呈现的视图控制器。 The view controller hierarchy generally maintains the strong references to the view controllers. 视图控制器层次结构通常维护对视图控制器的强引用。 So, when you dismiss the presented view controller, it is deallocated and the potential strong reference cycle is resolved. 因此,当您关闭所呈现的视图控制器时,它将被解除分配,并且可以解决潜在的强参考周期。

Often, we'll instinctually employ the weak protocol-delegate pattern (simply because it prevents strong reference cycles from occurring at all). 通常,我们会本能地使用weak协议委托模式(仅仅因为它可以防止强引用循环发生)。 But sometimes you will use strong references. 但有时您会使用强引用。 The most common strong reference pattern is NSURLSession whose delegate is a strong reference. 最常见的强引用模式是NSURLSessiondelegate是一个强引用。 As the documentation for init(configuration:delegate:delegateQueue:) warns us: 正如init(configuration:delegate:delegateQueue:)文档警告我们:

The session object keeps a strong reference to the delegate until your app exits or explicitly invalidates the session. 会话对象保留对delegate的强引用,直到您的应用退出或显式使会话无效。 If you do not invalidate the session by calling the invalidateAndCancel() or finishTasksAndInvalidate() method, your app leaks memory until it exits. 如果您没有通过调用invalidateAndCancel()finishTasksAndInvalidate()方法使会话invalidateAndCancel() ,则您的应用程序会泄漏内存,直到它退出。

While this might seem paradoxical, the advantage of this strong reference pattern is that the session knows that it can safely call its delegate methods without fear of the object having been deallocated. 虽然这可能看似矛盾,但这种强大的参考模式的优点是会话知道它可以安全地调用其委托方法而不必担心对象已被解除分配。 (As an aside, this strong delegate behavior of NSURLSession rarely rears its ugly head, because we often use the completion handler methods and don't employ the delegate methods at all, and when we do employ delegate methods, we often have some object other than a view controller as the delegate for the session.) NSURLSessionNSURLSession这种强大的委托行为很少会让它变得丑陋,因为我们经常使用完成处理程序方法而根本不使用委托方法,而当我们使用委托方法时,我们经常会有一些其他对象而不是视图控制器作为会话的委托。)

In short, you really have to evaluate each situation and determine whether the weak reference that we instinctually lean towards is better, or whether you have one of those cases where your protocol is better served with strong references. 简而言之,你真的必须评估每种情况,并确定我们本能地倾向于弱的参考是否更好,或者你是否有其中一种情况,你的协议更好地服务于强引用。

Why it's weak: A weak reference is a reference that does not keep a strong hold on the instance it refers to, and so does not stop ARC from disposing of the referenced instance. 为什么它很弱:弱引用是一个引用,它不会强制保留它引用的实例,因此不会阻止ARC处理引用的实例。 This behavior prevents the reference from becoming part of a strong reference cycle. 此行为会阻止引用成为强引用循环的一部分。 Or simply, You resolve strong reference cycles by defining some of the relationships between classes as weak or unowned references instead of as strong references. 或者简单地说,您可以通过将类之间的某些关系定义为弱引用或无引用而不是强引用来解析强引用循环。

And it's "!" 它是“!” after weak because it's implicitly unwrapped. 在弱之后因为它被隐含地打开了。 It's gonna have a value. 它会有价值。

Sometimes it is clear from a program's structure that an optional will always have a value, after that value is first set. 有时从程序的结构中可以清楚地看出,在首次设置该值之后,可选项将始终具有值。 In these cases, it is useful to remove the need to check and unwrap the optional's value every time it is accessed, because it can be safely assumed to have a value all of the time. 在这些情况下,每次访问时都不需要检查和解包可选的值,因为可以安全地假设它始终具有值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM