Delegate Swift Protocol Cannot Prevent Loop Preservation Problem

In Swift, if I create a delegate protocol, it can be negotiated using the class and structure.

protocol MyDelegate { // Can be conformed to by class or struct } 

The problem arises when I declare a delegate. If the delegate is an instance of the class, I want the variable to be weak in order to avoid saving the loop. If this is a structure, there is no such need - in fact, Swift will not allow me to make the delegate variable weak. Note. I know how to create a weak delegate, but the key question is: if you create a delegate protocol that can be weak, unless you make it compatible only with the class, you cannot enforce the persistence loop.

 class MyClass { // Want weak var here to avoid cyclical reference // but Swift won't allow it because MyDelegate can be // conformed by struct as well. Dropping weak means // cyclical reference cannot be prevented weak var delegate: MyDelegate? } class MyConformingClass: MyDelegate { } or struct MyConformingStruct: MyDelegate { } 

It seems we need to declare that the protocol will be for the class only at all times, for example, because a non-regular delegate protocol cannot prevent save cycles:

 protocol MyDelegate: class { } 

The fact that Swift allows you to shoot in the foot in this way seems to contradict his design philosophy in safety.

+5
source share
2 answers

It takes two save cycles ...

If you really want to do it this way, then why not leave weak and just make it a strong link. You will only have a problem if the delegate also maintains a strong reference to the object for which he delegated.

Thus, the delegate must make sure that any reciprocal links are weak, which should be possible all the time, since MyClass is a class, and therefore you can always declare a weak link to it.

0
source

If you really want to maintain a protocol for a class or structure, you can always save the delegate in separate base variables. That way, you may have one weak point when the delegate is a class. On the lines of the following:

MyDelegate protocol {// May correspond to a class or structure}

 class MyClass { private weak var delegateFromClass: AnyObject? private var delegateFromStruct: MyDelegate? var delegate: MyDelegate? { get { return (delegateFromClass as? MyDelegate) ?? delegateFromStruct } set { if newValue is AnyObject { delegateFromClass = newValue as? AnyObject delegateFromStruct = nil } else { delegateFromClass = nil delegateFromStruct = newValue } } } } class MyConformingClass: MyDelegate { } struct MyConformingStruct: MyDelegate { } print(" \(MyConformingClass() is AnyObject) \(MyConformingStruct() is AnyObject)") 
0
source

Source: https://habr.com/ru/post/1239349/


All Articles