誰かがSwiftのデリゲートポインタに「弱い」割り当てを使用するときと使用しないときを説明できますか?
私の理解では、クラスとして定義されていないプロトコルを使用する場合、デリゲートポインターをweakに割り当てることはできません。
protocol MyStructProtocol{
//whatever
}
struct MyStruct {
var delegate: MyStructProtocol?
}
ただし、プロトコルがクラス型プロトコルとして定義されている場合、デリゲートを弱いポインターに設定しますか?
protocol MyClassProtocol:Class{
//whatever
}
class MyClass {
weak var delegate: MyClassProtocol?
}
私は正しいですか? AppleのSwiftガイドでは、クラスプロトコルの例は弱い割り当てを使用していませんが、私のテストでは、デリゲートが弱く参照されていない場合、強い参照サイクルが見られます。
通常、クラスプロトコル(class
キーワードで定義)を弱くして、 "強い参照サイクル"(以前は "保持サイクル"と呼ばれていました)のリスクを回避します。デリゲートを弱くしないということは、本質的に強い参照サイクルがあることを意味するのではなく、単にcouldを持っていることを意味します。
ただし、struct
型はstruct
型が「参照」型ではないため、強い参照サイクルのリスクが大幅に減少します。したがって、強い参照サイクルを作成することは困難です。ただし、デリゲートオブジェクトがクラスオブジェクトである場合、プロトコルをクラスプロトコルにして弱くすることができます。
私の意見では、クラスデリゲートを弱くすることは、強い参照サイクルのリスクを部分的に軽減することです。それは本当に「所有権」の問題です。ほとんどのデリゲートプロトコルは、問題のオブジェクトがデリゲートの所有権を主張するビジネスを持たない状況ですが、問題のオブジェクトがデリゲートに何かを通知する(または何かを要求する)機能を提供しているだけです。
デリゲートは(編集:一般に)常に弱者でなければなりません。
b
がa
のデリゲートであるとしましょう。 a
のdelegate
プロパティはb
になりました。
b
がなくなったときにc
を解放したい場合
c
がb
およびc
への強い参照を保持している場合、b
をc
で割り当て解除する必要があります。ただし、a
で強力なデリゲートプロパティを使用すると、b
はa
を強く保持しているため、b
は割り当て解除されません。弱参照を使用すると、b
がc
から強参照を失うとすぐに、b
が解放されると、c
は解放されます。
通常、これは意図された動作であるため、weak
プロパティを使用する必要があります。