(UIkit)delegateのメソッドが呼ばれない問題とdelegateの具体例

# 問題のコード
結論から言いますと、自分の設定ミスです。涙
むしろ呼んでませんでしたね。と言うことで、サンプルコードを見てみます。
playgroundで動かしてみたサンプルコードです。
AddViewControllerでデリゲートを通して、saveFruitを呼び出し、ViewControllerのfruitsへ追加するという簡単な処理。、、、のはずが、うまく動かず、、、

``` swift
protocol AddViewControllerDelegate: AnyObject {
    func saveFruit(fruit: String)
}

class AddViewControllerSample {//委譲する側
    
    var apple = "りんご" //（仮）ユーザー入力項目
    weak var delegate: AddViewControllerDelegate?

    func save(){
        //デリゲートのメソッドを呼ぶ。
        delegate?.saveFruit(fruit: apple)//🟥nil
    }

}

class ViewControllerSample: AddViewControllerDelegate { //委譲される側
    
    var fruits: [String] = []
    
    func saveFruit(fruit: String) {
        fruits.append(fruit)//🟥呼ばれない
        print(fruit)
    }
    
}
let viewControllerSample = ViewControllerSample()
let addViewControllerSample = AddViewControllerSample()
//saveItemを呼び出す。
addViewControllerSample.save()//🟥[]
```

# 原因
原因はこの２つだと思っています。
1. 糖衣構文（シンタックスシュガー）を理解できていなかった。
2. デリゲートの設定忘れ。
 
糖衣構文（シンタックスシュガー）とは、構文を短くした書き方です。
今回の例で言うと、AddViewControllerSampleクラスのsaveメソッドの中の **delegate?.saveFruit(fruit: apple)** の部分ですね。
これをシンタックスシュガーを使わずに書くと以下のようになります。
```swift
if let delegate = delegate {
           delegate.saveFruit(fruit: apple)
        } 
```
if let {} を使ってオプショナルバインディングすればわかりやすいのですが、不慣れなシンタックスシュガーを使うと上の処理が走っていることをすっかり忘れていました。（戒）
そうです。。。delegateが設定されていないと言うことは、nilのためdelegate.saveFruit(fruit:apple)が書かれた、コードブロックの処理は呼ばれません。そして、nilと言うことはViewControllerをデリゲートに設定できていないと言うことです。
# 解決
**addViewControllerSample.delegate = viewControllerSample**の箇所でviewControllerSampleのViewControllerを代入してあげます。これで、設定完了です。無事動きました！！
```swift
let viewControllerSample = ViewControllerSample()
let addViewControllerSample = AddViewControllerSample()
//🟥デリゲートを設定する。
addViewControllerSample.delegate = viewControllerSample
//saveItemを呼び出す。
addViewControllerSample.save()//["りんご"]
//print(viewControllerSample.fruitName)
```
# 今回のdelegateパターンを図を用いて解説です。
![スクリーンショット 2023-08-20 12.04.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3232025/56ffb164-22ac-3939-8199-84898c64878d.png)
1. AddViewControllerSampleクラスがViewControllerSampleクラスを使う。
2. AddViewControllerSampleクラスがViewControllerSampleクラスの saveFruit(fruit: String)メソッドを呼び、値を渡す。
3. ViewControllerSampleが受け取った”りんご”を配列の中へ追加する。
![スクリーンショット 2023-08-20 12.05.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3232025/30d7ac28-54b3-8630-faf5-e48a9a1ea397.png)

## 2024年5月11日追加

アプリ道場サロンの方から実生活で例えるデリゲートの具体例をもらい実際に書いてみました。
初学者でなかなかdelegateのイメージしにくかったところ、実生活の場面を創造して説明していただき、それを実際に書き起こすことで少しではありますが、理解を進めることができました。
間違っているところがあれば、ご指摘いただけると大変ありがたいです。
[アプリ道場Twitter](https://twitter.com/AppCreatorDojo)

```swift
protocol SinglePhase100V { //家庭用コンセントの差し込み口
      func conductElectricity() //電気を流す
  }
  
  class HouseConsent { //家のコンセント
      var singlePhase100V: SinglePhase100V? //最初は何も差されていない状態。
      
      func workElectricalAppliances() { //コンセントに差されていれば、差されたものが起動する。
          if let singlePhase100V {
              singlePhase100V.conductElectricity()
          } else {
              print("nil")
          }
      }
  }
  
  class Hairdryer: SinglePhase100V { //単相１００Vの差し込み口に適合
      func conductElectricity() { //電気を流す
          print("風が吹く")
      }
  }
  
  class PS5: SinglePhase100V {
      func conductElectricity() {
          print("ゲーム起動")
      }
  }
  
  var houseConsent = HouseConsent()
  let hairdryer = Hairdryer()
  
  houseConsent.singlePhase100V = hairdryer //コンセントに差し込む
  houseConsent.workElectricalAppliances() //電気が流れ起動する。どの関数が呼ばれるか確定しない。実行時に確定。
```