質問: "Subtitle \(dataArray[indexPath.row])" return cell } } ``` いくつか質問があります。 上記のプログラムで ``` @IBOutlet weak var tableView: UITableView! ``` このtableViewは関数ですか?それともインスタンスですか? また ``` func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return dataArray.count } ``` で引数となっているnumberOfRowsInSectionはメソッドだと思うのですが それがどうして引数になるのですか? 最後にこのプログラムは関数を定義しているだけなのに どうして実行するのかが分かりません。 たくさんの質問をすいませんがよろしければ 回答を宜しくお願いします。
回答: > > `@IBOutlet weak var tableView: UITableView!` > > このtableViewは関数ですか?それともインスタンスですか? > > > `tableView`は、**プロパティ**(Property)です。その下の`dataArray`と同じ。`@IBOutlet`、`weak`など修飾子が複数ついていますが、それらを外してしまえば、`tableView`はひとつの**変数**です。 たとえていうなら、変数は容器を指し、**インスタンス**は、その内容を指します。質問の文脈からすれば、`tableView`は容器、すなわち変数とみるべきです。 置いてある場所や、使い道によって、同じモノでも、異なる名称になるのは、私たちの日常でよくあることです。Swiftにおいても、クラスや構造体などに属する関数のことを、**メソッド**(Method)、クラスや構造体などに属する変数のことを**プロパティ**と呼びます。 以上から、`tableView`は、プロパティと呼ぶのが妥当です。 なお、プロパティには2種類あり、**格納型プロパティ**(Stored Property)、**計算型プロパティ**(Computed Property)に分かれます。ここでは格納型プロパティを指しています。 そして、プロパティについて勉強していくと、プロパティが単なる変数ではなく、じつはもっと複雑なものだということがわかってきます。学習を重ね、知識を深めていってください。 > > `func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int` > > で引数となっている`numberOfRowsInSection` > > はメソッドだと思うのですが それがどうして引数になるのですか? > > > メソッドではありません。**ラベル**(Argument Label)です。 関数(メソッド)は、関数の引数にはなりません。ひとまとまりのプログラムを、引数に渡したいことは、ままありますが、そういう用途には、**クロージャ**(Closure)が用意されています。 関数の書式について、基礎部分を説明します。Swiftは、C言語の書式を踏襲したものになっていますが、随所にC言語と異なる箇所があります。 関数の基本書式は、 ``` // 定義の書式 func area(width: Float, height: Float) -> Float { return width * height } // 呼び出す書式 let a = area(100.0, height: 100.0) ``` 関数を呼び出すとき、第2引数以降に、ラベル`height`がつくのが、Swiftの特徴です。 ※ここでは、Swift2に基づいて説明をしています。Swift3では、第1引数だけ特別扱いするのは、複雑なだけでわかりにくいという意見を取り入れて、第1引数にもラベルがつくようになります。 ``` func area(width: Float, height: Float) -> Float { return width * height } let a = area(width: 100.0, height: 100.0) ``` 基本書式では、引数名がそのままラベル名になりますが、引数名とラベル名を異なるものにすることが可能です。 ``` func area2(width w: Float, height h: Float) -> Float { return w * h } let b = area2(width: 100.0, height: 100.0) ``` ラベル名と引数名を併記して定義します。 質問の`func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int`は、このパターンの書式に該当します。`numberOfRowsInSection`がラベルで、`section`が引数です。 ついでに、いちいち引数にラベルをつけるのは、うざったいと考える向きには、ラベルを省略する書式も用意されています。 ``` func area3(w: Float, _ h: Float) -> Float { return w * h } let c = area3(100.0, 100.0) ``` アンダーバー(_)を使って、省略を指示します。 > > 最後にこのプログラムは関数を定義しているだけなのに どうして実行するのかが分かりません。 > > > この点については、**デリゲート**(Delegate)というデザインパターンについて勉強していただく必要があります。iOSのフレームワークにおいては、多用されるデザインパターンですので、いちど腰を据えて学習するだけの価値があります。 とりあえずかんたんに説明します。Delegateは、直訳すると、「委譲」、「委託」となります。 `UITableView`は、いうまでもなくテーブルを表示するViewですが、テーブルを表示するには、まず表示するデータ、セクションの数、セクションごとの行数、行ごとの高さ、セルごとに表示するデータなどなど、多数の要素が決定しないと、なにも始まりません。たとえば、`UIImageView`は、イメージを表示するViewですが、サイズとイメージデータを、インスタンスのプロパティとして代入すれば、イメージが表示されます。`UITableView`でも、いくら必要な要素が多数あるとしても、すべてプロパティに代入すれば、コンテンツの表示はできるはずです。 しかし、`UITableView`は、必要な要素を内部のプロパティに持つのではなく、そのほとんどを、外部の別のインスタンスに委託するという形態を取っています。`UITableView`は、`ViewController`インスタンスに定義してある`func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int`というメソッドを呼び出して、自らのセクションごとの行数を決定します。 このメソッドは「呼ばれていないのに実行される」のではなく、`UITableView`が呼んだので、実行されます。 ※C#などでは、Delegateは言語の一部として扱われますが、Swiftはそうではありません。純粋にSwiftに関する書籍、情報だけあたってみても、Delegateに関する記述が見つからないことがあります。iOSや、UIKitに関連づけて検索したほうがいいでしょう。