目指せ!iPhoneアプリ開発エキスパート

第5回アクションとObjective-C

さて、前回に引き続き、プログラミングの基礎について解説します。今回は、おもにObjective-Cについて説明します。

アクションのおさらい

いよいよObjective-Cに触れていきます。前回次のようなアクションを書きました。

- (IBAction)myAction1:(id)sender {

    int kakaku = [[motone text] intValue];

    switch([waribiki selectedSegmentIndex]){
    case 0:
        kakaku = kakaku * (1.f - 0.2f);
        break;
    case 1:
        kakaku = kakaku * (1.f - 0.3f);
        break;
    case 2:
        kakaku = kakaku * (1.f - 0.4f);
        break;
    case 3:
        kakaku = kakaku * (1.f - 0.5f);
        break;
    default:
        break;
    }

    [kekka setText:[NSString stringWithFormat:@"%d", kakaku]];

}

この中身、すなわち最初の { から最後の } までに書かれているものが、セグメンテッドコントロールで割引率が変更された際に実行されるアクションとなっています。

Interface Builderで設定したアクションの中身をObjective-Cで記述
Interface Builderで設定したアクションの中身をObjective-Cで記述

このアクションの中身を先頭から見ていきましょう。

値を取り出す

テキストフィールドに入力された値

まずは、ユーザが入力した金額の値を取り出します。パーツの持つ値はすべてアウトレットを通して受け取ります。ここではテキストフィールドが「motone」というアウトレットに接続されていますので、motoneを使ってテキストフィールドに打ち込まれた値を取り出すことができます。

int kakaku = [[motone text] intValue];

イコールより右側が、アウトレットを通してパーツに入力されている値を取り出すための命令です。イコールの左側にあるkakakuに金額が入ります。先頭についている「int」は、その後に続くkakakuが「整数である」ことを表しています。

セグメンテッドコントロールの値

次に、ユーザが選択した割引率を取り出します。セグメンテッドコントロールが接続されているアウトレット「waribiki」を通して取得します。

ここで取り出すことができるのは、セグメンテッドコントロールの「何番目のボタンが押されているか」です。何番目のボタンにどんな割引率が設定されているかはわかっていますので、もし一番左が選ばれているならば20%、あるいは左から2番目ならば30%…というふうに見ていくことになります。

何番目のボタンが押されているか、その番号をアウトレットを通じて取り出すには、次のように書きます。

[waribiki selectedSegmentIndex]

プログラム中でこれを記述した部分が、セグメンテッドコントロールで選ばれている番号に置き換わります。

ここで気をつけることは、プログラミングの世界で番号を数えるときは、特別な理由がない限り「0」からはじまるということです。号令をかけるときは「番号、1、2、3・・」と数えるのが普通ですが、プログラミングの世界では最初の番号は0です。0、1、2、3…と続きます。ですから、セグメンテッドコントロールのボタンの番号も、一番左は「0番」です。その右が1番、その右が2番、そして一番右が3番です。

プログラムを扱う際このようなシチュエーションは多々ありますので、ここで慣れておきましょう。

Objective-Cの構文

2種類のパーツについて値の取り出し方を学びましたが、C言語に触れたことのある方はいずれもイコールより右側の書き方がObjective-C独特のものであることをおわかりいただけると思います。ここで、Objective-Cの書き方について触れておきましょう。

ここで行っているのは「テキストフィールドに入力された金額を取り出す」「セグメンテッドコントロールで選択されたボタンの番号を取り出す」といった、Interface Builderで設置したパーツに対し、アウトレットを通して何らかの操作を行って情報を得る「メソッド呼び出し」といわれるものです。

Objective-Cのメソッド呼び出し
Objective-Cのメソッド呼び出し

メソッド呼び出しは [ ] でくくられた構文を使って行います。まずは「レシーバ」と呼ばれる、メソッド呼び出しの対象となるものを指定します。

Interface Builderで設置したパーツを対象とする場合は、そのパーツに接続したアウトレットがレシーバとなります。レシーバの後にスペースを入れ、続いて「メッセージ」と呼ばれるレシーバに動作させる内容を示した文を記述します。レシーバとメッセージの間に「の」を入れるとわかりやすいでしょう。実際にどんなメッセージが使えるかはレシーバによって異なります。この大括弧にくくられたレシーバとメッセージの組み合わせを「メッセージ式」と呼びます。

メッセージ式によって得られる結果もまたレシーバとなる場合があります。テキストフィールドに設定された値を取り出すメッセージ式では、まず「motone」に対して「text」を実行して取り出した「文字」に対し、さらに「intValue」というメッセージを使って「整数」として取り出すよう、最初のメッセージ式の結果をレシーバとしてさらにメッセージ式を作っています。このように入れ子になっているメッセージ式は、[ ] でくくられた単位で解釈していくと理解しやすいでしょう。

計算と結果の表示

switch文による条件分岐

次は割引後の値段の計算です。⁠kakaku」に入っている金額と割引率を使って計算しますが、割引率はセグメンテッドコントロールで選ばれているボタンの番号によって、あらかじめ決められた割引率から選択する必要があります。0番ならば20%、1番ならば30%、2番ならば40%、そして3番ならば50%となります。割合を小数で表し、1から引いたものを kakaku にかけて割引後の金額を求めます。たとえば、0番が選ばれている場合、すなわち割引率が20%の場合は次のような式になります。

kakaku = kakaku * (1.f - 0.2f);

小数の後ろについている「f」「float」の頭文字で、その数字が小数であることを示すためのものです。プログラムは、同じ数字でもそれが整数なのか小数なのかをはっきりと区別する場合があります。最初のうちは、結果が小数となる計算で扱う数字に「f」をつけておくという感覚でかまわないでしょう。整数を小数として扱う場合は、⁠1f」ではなく「1.f」のように小数点を加えて表現します。

複数の割引率を扱うために、switch文を用いて分岐をします。switch文はある条件に基づいていくつかの異なる処理をさせるためのプログラム文です。switchに続く ( ) 内に処理を分岐させるための条件を、続いて { } の中に実際の分岐と処理内容を記述します。

switch([waribiki selectedSegmentIndex]){
case 0:
    kakaku = kakaku * (1.f - 0.2f);
    break;
case 1:
    kakaku = kakaku * (1.f - 0.3f);
    break;
case 2:
    kakaku = kakaku * (1.f - 0.4f);
    break;
case 3:
    kakaku = kakaku * (1.f - 0.5f);
    break;
default:
    break;
}

ここでは、caseに続く数字がセグメンテッドコントロールの番号と一致した場合、その後の「:」⁠コロン)に続いて書かれているプログラムを「break;」まで実行します。最後の「default:」はどの条件にもあてはまらない場合の処理で、今回のように起こりえるすべての条件が書かれている場合には無くても問題ありません。見てわかるとおり実際に「default:」の条件の中ではすぐに「break;」が書かれており、何の処理も行っていません。

これで「kakaku」に割引後の金額が入りました。⁠kakaku」は整数なので、金額として表示する際にはそのまま扱うことができます。

画面への表示

「kakaku」の値を画面に表示してみましょう。ラベルにこの値を設定することで表示します。ラベルと接続しているアウトレットは「kekka」です。

[kekka setText:[NSString stringWithFormat:@"%d", kakaku]];

値の受け取りと同様にアウトレットをレシーバとするメッセージ式を使って書きますが、今回は値の設定ですので、実際に設定する値をメッセージ式の中に含める必要があります。そこで登場するのが、引数です。

引数を含むメッセージ式
引数を含むメッセージ式

引数は、レシーバに何らかの値を渡すための仕組みです。メッセージにある「:」⁠コロン)より後の部分が引数です。一方「:」より前の部分、すなわち「setText」「メソッド」と呼びます。このように、何らかの値をレシーバに渡す必要があるメッセージは、メソッドと引数の組み合わせで成り立っています。ここでは、ラベルが接続されているアウトレット「kekka」に対して「setText」メソッドで設定する文字を引数として指定しています。

この「setText」メソッドの引数として指定できるのは、数字ではなく文字(正しくは文字列)だけです。ここに数字を指定したい場合、数字をいったん文字列に変換してから指定する必要があります。そこで「NSString」というものを使って文字列を組み立てます。

「NSString」は文字列に関するいろいろな操作を行うためのもので、これをレシーバとしてメッセージ式を書くことで機能します。ここでは「stringWithFormat」で文字列の中身を整形することを指定し、引数としてその整形の方法を指示するためのルールと、文字に変換したい値「kekka」を渡しています。こうすることで「NSString」をレシーバに指定した [ ] の部分が文字列に置き換わり、⁠setText」の引数として指定できるようになるのです。値の受け取りで書いた時と同様に、メッセージ式を入れ子にして書くことができます。

こうしてアウトレット「kekka」を通して設定した文字列が、⁠kekka」に接続された画面上のラベルに表示されるという仕組みです。

難しい話はあとまわし

「オブジェクト指向プログラミング」という言葉をご存知でしょうか。本来はプログラムを書く効率をあげたり、複雑なプログラムをより確実に動かすことを目的とした、いわばプログラミングのテクニックのようなものです。ところが、今や書店にはオブジェクト指向プログラミングの専門コーナーが設けられるほどさまざまな本が並び、なんだか難しそうだ、概念を理解するだけでも大変そうだ、なんてイメージを持たれている方もいらっしゃることでしょう。iPhoneアプリの開発でも、このオブジェクト指向プログラミングは避けては通れない道になっています。

オブジェクト指向プログラミングは、それを自分のものにしてしまわない限り、とても敷居が高く感じられるものです。そしてそれを自分のものにするためには、多くの時間を費やすことになってしまうかもしれません。そんなことではせっかく思いついた素晴らしいアイデアも、時間とともに台無しになってしまいます。

しかし、ここまでのプログラミング作業において、オブジェクト指向プログラミングを意識することはほとんどありませんでした。Interface Builderでパーツを配置し、アウトレットと接続して、アウトレットを使ってメッセージ式を作るという、とても直感的でわかりやすい作業のみでアプリを動かすことができました。

クラスとインスタンスの関係
クラスとインスタンスの関係

クラスを設計しインスタンスを生成するという作業は、無意識のうちにすべてInterface Builder上で行っています。Interface Builderを積極的に使ったアプリ開発では、まずパーツを配置して画面を構成し、そこからクラスファイルを生成する手法をとっています。iPhoneアプリのような小規模な開発では、この手法はオブジェクト指向プログラミングの良いところを活かしつつ難しいところは後回しにできるため、たいへん効率の良いものとなっています。

Cocoa Touchを使ったiPhoneアプリの開発では、すでにオブジェクト指向プログラミングを理解している方もそうでない方も同じスタート地点に立つことができます。Cocoa Touchを実際に使うことは、オブジェクト指向プログラミングを実践していることと同じ。学ぶより先に使ってしまいましょう。難しいことは、アプリが動いた後でじっくり学べば良いのです。その頃にはプログラミングに対してさらに興味が沸いてくることでしょう。

公開するためのアプリ作り

次回からは実際にApp Storeで公開することを目指し、アプリの見栄えを調整するテクニックや、Cocoa Touch で提供されているより多くのパーツの使い方を学んでいきます。さらにはアプリを実際にiPhoneで動作させるための方法、App Storeで公開するための手続きなどについても説明していきます。これまでに学んだInterface Builderの使い方と、アウトレットおよびアクションの設定をしっかりと復習しておきましょう。

おすすめ記事

記事・ニュース一覧