基本的な実装
protocol ClassADelegate: AnyObject {
func call()
}
class ClassA {
weak var delegate: ClassADelegate?
func test() {
delegate?.call()
}
}
class ClassB {
let a = ClassA()
init() {
a.delegate = self
}
}
extension ClassB: ClassADelegate {
func call() {
Swift.print("Hello World")
}
}
ポイント
- 0から自作のDelegateを作る時はAnyObjectをつける
- delegateのプロパティは
weak var
にする(強参照によるメモリリーク対策)
すでにDelegate
をもつクラスを拡張したDelegateを作る時
protocol CustomeTextViewDelegate: NSTextViewDelegate {
func call()
}
// NSTextView はすでにdelegateを持っている
class CustomeTextView: NSTextView {
private var customDelegate: CustomeTextViewDelegate? {
return self.delegate as? CustomeTextViewDelegate
}
func test() {
customDelegate?.call()
}
}
class ClassA: NSView {
let a = CustomeTextView()
required init?(coder: NSCoder) {
super.init(coder: coder)
a.delegate = self
}
}
extension ClassA: CustomeTextViewDelegate {
func call() {
Swift.print("Hello World")
}
}
ポイント
-
self.delegate as? CustomeTextViewDelegate
のようにすでにあるdelegateをキャストする形で使う.キャストできた時だけ発動する仕組み.
実装不要なDelegateメソッドを作りたい場合
パターンA
protocol ClassADelegate: AnyObject {
func requiredFunc()
func optionalFunc()
}
extension ClassADelegate {
func optionalFunc() {}
}
class ClassA {
weak var delegate: ClassADelegate?
func callRequire() {
delegate?.requiredFunc()
}
func callOptional() {
delegate?.optionalFunc()
}
}
class ClassB {
let a = ClassA()
init() {
a.delegate = self
}
}
extension ClassB: ClassADelegate {
func requiredFunc() {
Swift.print("Hello World")
}
// optionalFuncは実装しなくてもコンパイル通る
}
ポイント
-
extension
で一度空っぽの実装をしてしまう.
パターンB
@objc protocol ClassADelegate: AnyObject {
func requiredFunc()
@objc optional func optionalFunc()
}
class ClassA {
weak var delegate: ClassADelegate?
func callRequire() {
delegate?.requiredFunc()
}
func callOptional() {
delegate?.optionalFunc?()
}
}
class ClassB {
let a = ClassA()
init() {
a.delegate = self
}
}
extension ClassB: ClassADelegate {
func requiredFunc() {
Swift.print("Hello World")
}
// optionalFuncは実装しなくてもコンパイル通る
}
ポイント
-
@objc
修飾詞をつける.
ここによると,パターンAの方がSwiftらしくていいらしい.