33026


プロトコルとデリゲートについて勉強しています。

デリゲートの中身については  
ある程度イメージもできて理解できたと思います。

だけれど、詳しい過程？進み方が理解できません。

例

[code]

    class A:UITextFieldDelegate{
    
    @IBOutlet var textField:UITextField!
    override func viewDidLoad() {
            super.viewDidLoad()
            // selfをデリゲートにする
            self.textField.delegate = self
        }
    func textFieldShouldReturn(textField: UITextField) -> Bool{
    //リターンキーが押されたとき
    }
    }
    
[/code]

こういうプログラムがあったとき、  
リターンキーが押された後、まずはどこにその通知が行くのでしょうか？  
クラスAにUITextFieldDelegateが移譲されているので  
直接クラスAのfunc textFieldShouldReturn 関数に通知されるのでしょうか？

質問が解りにくいかもしれませんが  
delegateの処理の進み方が知りたいです。

宜しくお願いします。


CC BY-SA 3.0
2017-03-01T14:28:07.137
33023
2022-10-06T07:52:46.817
2022-10-06T07:52:46.817
19110
18539
question
swift delegate
swift デリゲートの通知の過程


`UITextField`クラスの実装が、どうなっているか見ることができないので、Delegateの理解がむずかしくなっています。そこで、必要最小限の自作Delegateを作って、その構造を見てみましょう。クラス`Sample`がDelegateの移譲元、クラス`Foo`が移譲先です。

[code]

    class Sample {
    
        var value: Int
    
        weak var delegate: SampleDelegate?
    
        init() {
            value = 0
        }
    
        func actionAnyThing() {
            // Send Delegate
            if let delegate = delegate {
                delegate.sampleDidAnything(object: self)
            }
        }
    }
    
    protocol SampleDelegate: class {
        func sampleDidAnything(object: Sample)
    }
    
    extension SampleDelegate {
        func sampleDidAnyThing(object: Sample) {
            print("Delegate not declared")
        }
    }
    
    class Foo: SampleDelegate {
    
        // Delegate Method
        func sampleDidAnything(object: Sample) {
            print("Foo said \"Sample value = \(object.value)\"")
        }
    }
    
    let sample = Sample()
    sample.value = 100
    let foo = Foo()
    sample.delegate = foo
    sample.actionAnyThing()
    
    // 出力：Foo said "Sample value = 100"
    
[/code]

わざわざDelegateという名前がついているのだから、さぞ複雑なメカニズムと思われるでしょうが、実態は、ただほかのインスタンスを参照して、そのメソッドを呼んでいるだけです。Delegateの意味は、移譲元のクラスの具体的な実装がわからなくても、プロトコルの宣言を調べることで、どういうメソッドが移譲元から送られるのかがわかることです。  
`UITextField`クラスについてみると、その実装に、リターンキーが押された時の処理をするメソッドが定義されており、その定義の中で、Delegateメソッド`textFieldShouldReturn(textField:)`を呼んでいることが推理できます。

* * *

回答と関係ない部分の説明を少し。  
Delegateのメソッドを、プロトコルで宣言するのは、ご存知のとおりですが、エクステンション`extension
SampleDelegate`はなにをしているのかというと、Delegateメソッドを実装するインスタンスが存在しないときに、備えているのです。エクステンションがないと、プロトコル`SampleDelegate`を準拠したクラスは、かならずそのメソッドを定義しなければいけない文法になっているのですが、実際は、定義するメソッド、定義する必要のないメソッドが出てくるので、定義しないことを許容するために、エクステンションが用意されます。


CC BY-SA 3.0
2017-03-01T22:45:31.470
33026
2017-03-01T22:45:31.470
18540
33023
answer