delegateについてようやく理解できたので書いておく[Swift]
iPhoneアプリ開発の学習を開始してから一ヶ月、常に私を悩ませてきた問題がある。
[Delegate]である、これが本気で何言ってるかわからない。
が、先ほど電撃のように理解したので書いておく。
delegateはなぜわかりにくい。
私はdelegateの理解のためインターネットを彷徨ったが、だいたい出てくるのはこの2つのワードである。
「委譲すること」
「依頼人になるための仕組み」
このように、まるで人間の持つ仕組みかのように書かれていた。
プログラムは人間では無いので、確かに人間を例に用いて説明するのは手っ取り早いかもしれないが初学者としては理解しにくかった。
また、「代理人になる仕組み」というものを理解しようとしても、そもそもdelegateというものが何のために存在しているのかわからないため、さっぱりわからない。
なんのためにdelegateが存在するのか。
私はdelegateの存在理由、一言で言えばメソッドの独立性を高めるためだと考える。
例えば、テキストフィールドに住所を入力すると、その住所から緯度と経度を求めるプログラムがあるとする。
このプログラムはざっくり、本当に分けると
住所(文字列)を入力される→緯度経度を求める
という構造をしている。
Appleの気持ちになって考えて見て欲しい。
仮にこれを1つのメソッドでまとめるとすると、どうなるだろうか。
「文字列を入力→なにかをする」
もしくは
「何かをする→緯度経度を求める」
という組み合わせを全て実装しなくてはならない。
Aplleが用意しなくてはならないクラス、メソッドは膨大な量になってしまう。
これに対してAppleがどうすればよいかというと、メソッドの組み合わせはユーザーの自由にできるような仕組みを作れば良いのだ。
そこで必要になってくるのが、そう[delagate]である。
先ほどの
「住所(文字列)を入力される→緯度経度を求める」
にdelegateを組み込んだ考え方をしてみる。
「住所(文字列)を入力される
→入力されたことを「緯度経度が求められるメソッド」にお知らせする
→お知らせを受けた「緯度経度を求められるメソッド」が緯度経度を求める。」
これのメリットがわかるだろうか、
お知らせ先が自由になったことにより、メソッド同士の組み合わせが自由になるのである!これはすごい!
まとめると、delegateが存在する理由というのは
『メソッドの組み合わせ(プログラムの組み方)を自由にするため』
言い換えれば
『個々のメソッドを独立した存在にさせるため』
(さっきの住所の例のようにdelegateの仕組みがないとメソッドの機能が限定されすぎてしまう)
なのである!
つまりdelegateとは
なにか「特定の動作の後」に、他の「自分にはない機能を持つメソッド」に
処理を行ってもらうためのお知らせを飛ばす仕組み!
である。
ダメ押しに例を挙げておく!
TextField上でリターンキーが押された時に、printメソッドを呼び出すよ!
class ViewController: UIViewController,UITextFieldDelegate {
@IBOutlet weak var adressField: UITextField!
@IBOutlet weak var displayMap: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
adressField.delegate = self //adressFieldのイベント時の通知先を自分自身(ViewController)に設定。
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool { //テキストフィールドでリターンキーが押されたタイミングでお知らせ
print("pushed Return") //リターンキーが押されたよ!
return true
}
delegate.selfの意味
ViewDidLoadの中の
tableview.delegate = selfの
selfは、ViewControllerを指している。
// // ViewController.swift // tableViewLecture // // Created by on 2018/08/24. // Copyright © 2018年 . All rights reserved. // import UIKit class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource{ override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. tableView.delegate = self tableView.dataSource = self } @IBOutlet weak var tableView: UITableView! override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } }
なぜ、いざ自分でコードを書こうとなると何も書けないのか
Swift学習を開始してから17日ほどが経過した。
現時点でやったこと
//書籍の内容理解,コードなぞり
//Udemy講座半分まで
【6日で速習】iOS 11 Swift 4アプリ開発入門決定版 20個のアプリを作る
簡単に言うと、文法を覚えてコードをなぞってアプリを作った。
いざ自分で作ろうとする
しかし、動画や参考書といったガイドラインを失ってしまうと何も始められない、なにからすればよいのかわからない。
例として、電卓のアプリを作ろうとしたがStory board上にレイアウトを作成した段階で自分でできることは終わったなと感じた。
なぜ自分でできないのか
考えられる要因
1.文法は理解できているが、そもそも開発を行う時の組み立て方がわからない
(swiftというよりプログラミング全般の問題)
2.文法がきちんと理解できていない
(型キャスティングやデレゲートなど、理解しているようで使う場面や必要性がわかっていないのでは?)
3.swift上で使うクラスの使用法の調べ方がわからない
(機能を実装するための部品が見つけられない、検索能力がない)
(英語力の問題なのか、Swiftの内容理解が足りないのか)
要因に対する解決策
1.開発の流れがわからない
これはSwiftなどのプログラミング言語の問題ではなく、プログラムを作ること全体に通ずるものだと考える。
まずは書籍に書いてあるソースコードなどから以下の内容を汲み取り、紙に書き出してみる。
1.簡易的な文章で、実装したいプログラムの流れを書く(人間だったらどうするか)
2.コンピュータも理解できるような手順を文章で書く
3.必要なデータ(要素)を書き出す
4.1-3を元にフローチャートを書く
参照:
2.文法がきちんと理解できていない
今回の場合における「理解できていない」は、「使い所がわからない」という言い方のほうが正しいと感じる。
すなわち、わからない文法に出くわしてしまった時は、なぜそれを使ったかを文章にして考える必要がある。
課題1:delegateを使用する理由についての記事を1つ書く
課題2:なぜここでこれを使うのか理解できないものをピックアップして記事を書く。
3.部品を探す能力(検索能力)
ちょっとこれどうすればいいのかわからないので優しいそこのあなたアドバイスくれてもいいのよ!
4.Appleが何をいってるかわからない
英語を読める人はSwift開発とてもイージーになると思います。なぜならXcode搭載の便利な機能の説明はほとんどAppleDeveloperに書いてあるから!
AppleDeveloperから汲み取らなくてはいけない内容は、例としてクラスをあげると
- プロパティとその用途
- このクラスの用途
- 用意されているメソッドとその用途
- メソッドの引数
など、結構限られていることがわかります。慣れていけば、どこに何が書いてあるかわかるようになるのかしら!現在Swiftを用いてアプリ開発している人はぜひどうやって情報を得ているのか教えてください!お願いします!
まとめ
自分でコードが書けない理由は
swiftより前の段階でできていないことだらけだから
先走らず基礎から固めていきましょ。
*1:文体がぐちゃぐちゃすぎる
戻り値のあるメソッドをエラーなく実行だけする方法
通常、メソッドを実行したい時は
メソッド名()
でよいのですが、実行したいメソッドが戻り値(Int型など)を持っている場合
このような書き方をしてしまうと
「使用していない変数があります(Result of call to 'displayUpdate()' is unused)」
といったエラーが出てしまいます。
このエラーは
_ = メソッド名()
と、アンダースコアに代入する形にすることにより回避できます。
まとめ
アンダースコアにメソッド名が代入されている時は、戻り値のあるメソッドを実行しようとしている。