アシアルの中の人が技術と思いのたけをつづるブログ

Interface Builderを使わずに作るiPhoneアプリケーション作成入門

タグ [  Tech  iPhone  ]
こんにちは、亀本です。

最近では、だいぶiPhoneアプリ開発に関するチュートリアルも日本語で散見されるようになってきて、以前よりも状況は改善されてきたかなーと思います。

そういった様々なチュートリアルが出てくる中でちょっと気になったのは、どれもこれもInterface Builder(IB)ばりばりに活用しようぜ!なチュートリアルだということ。

多分やり方的には正しいんですが、正直なところ自分がiPhone開発をしていく上で一番苦労したのがIBでした。
ぶっちゃけていうと、iPhoneのフレームワークであるUIKitなどの挙動や感覚がわからないうちからIBを使いこなすのは結構大変なんじゃないかなぁ、と思うのです。僕がへっぽこなだけかもしれませんが。

というわけで、チュートリアル読んだけど結局 IBチンプンカンプンで開発とかできねーYO!!という方、および一度に二つのことを覚えられないObjective-C初心者兼iPhone開発初心者に贈る、IBを極力使わないiPhoneアプリケーション開発入門を書いていこうと思います。

だって僕らプログラマだもん><全部コードで表現できた方がいいよね!

なお、僕自身もまだまだエキスパートには程遠く、完全に体当たりだけでiPhone開発を学んできたので、中には勘違いやおかしな点、そこはこう書くべき!などの点も含まれているかもしれません。
そういった点はどんどんご指摘いただけたらうれしいです。


ちなみに、ここではiPhone SDK等のインストールに関しては扱いません。そこまでだけで記事になってるのがあちこちにあると思うので、そういったものを参照してください。
だいたい、読者としても全くプログラミングが出来ない人ではなく、何かしらの言語で簡単なことは出来るかなーぐらいの人を想定しています。なので、空気読めばわかるぐらいの細かい言語仕様とかの説明は省きます。

なお、開発環境としてはiPhone 2.2 SDKを想定しています。

今回の目標

ここでは、単純なテーブルを表示させてみます。今回は初回なので、まずは理解しておくべき基本事項を説明しながら進めていきたいと思います。
普通なら最初は何もないところに[Hello, world!]なんでしょうが、多分iPhoneアプリを作る中で一番使用頻度が高く応用範囲が広いのが、テーブル表示です。なので、この記事ではTableviewを使うことを軸に進めていきます。


プロジェクトの作成

まずは、Xcodeを起動してこれから作成していくプロジェクトを生成します。
Xcodeのメニューから[ファイル]→[新規プロジェクト]と進み、新規プロジェクトのテンプレート選択画面に進みます。
ここで、iPhoneOSのApplicationカテゴリの中から、[Window-Based Application]を選択し、プロジェクトの名前を付けてください。ここではsamplePrjという名前で作成します。


プロジェクトの生成が終わると、Xcodeの編集画面が開きます。
ここでまず、プロジェクトが正常に生成されている確認の意味も込めて、試しにビルドしてみましょう。

Xcode上部の[ビルドして進行]ボタンを押すと、ビルドが完了した後iPhoneシミュレータが起動し、samplePrjアプリケーションが呼び出されます。
今はまだ、真っ白な画面が表示されますが、これに実装を施していきます。

基本的な呼び出しの仕組み

ほとんどのお約束事項はこの段階でXcodeがやってくれていますが、どういう流れでアプリケーションが呼び出されているか、の本当に基本的なところがわからないと、これから作っていく上で気持ち悪いですよね。
なので、ここでは簡単にアプリケーションの呼び出しの流れがどういう経路をたどっているのかを超ざっくり説明しておきます。

まず、Other Sourcesに入っているmain.mですが、ここにすべてのソースに先立って呼ばれるmain関数が実装されています。
Objective-CはC言語の拡張なので、C言語同様main関数からすべてが始まります。ヘッダーもC言語同様に.hファイルに記述します。ただし、実装を記述するのは.cではなく.mというファイルになります。

基本的に、このmain.mを編集することはありません。
この中で呼び出されているUIApplicationMain関数がiPhoneアプリケーションのフレームワークであるUIKitを呼び出すメソッドになっており、この関数内から、プロジェクトのClassesグループツリー内にあるxxxxAppDelegateというオブジェクト(ここではsamplePrjAppDelegate)が呼び出されます。
実際のiPhoneアプリケーションは、こちらに実装していきます。

ClassesのsamplePrjAppDelegate.mをみてみると、
  1. - (void)applicationDidFinishLaunching:(UIApplication *)application {    
  2.     // Override point for customization after application launch
  3.     [window makeKeyAndVisible];
  4. }
というメソッドが実装されています。このapplicationDidFinishLaunchingメソッドはUIApplicationのフックメソッドになっており、ここがあらゆる処理の起点になると考えておいてください。

これからテーブル等を実装していくのも、このメソッド側になります。

まずはテーブル表示
さて、基本的な流れを説明したところで、しばらくおまじないモードに入ってテーブルを実装してみましょう。
先ほど説明したapplicationDidFinishLaunchingメソッドを以下のように変更します。

  1. - (void)applicationDidFinishLaunching:(UIApplication *)application {    
  2.     // 以下の2行を追加
  3.     UITableViewController *tableViewController = [[UITableViewController alloc] initWithStyle:UITableViewStylePlain];
  4.     [window addSubview:tableViewController.view];
  5.     // Override point for customization after application launch
  6.     [window makeKeyAndVisible];
  7. }

さて、追記をしたところで、ビルドを実行してみましょう。
先ほどと異なり、何かテーブルらしきもの(^^;が表示されたかと思います。


では、ここでやっている処理をざっくりと解説していきます。

1行目の解説

まず1行目。この行では、変数の宣言と初期化を行っています。
  1. UITableViewController *tableViewController = [[UITableViewController alloc] initWithStyle:UITableViewStylePlain];
=の左辺は変数宣言で、UITableViewControllerオブジェクトを格納するための変数tableViewControllerを定義しています。
UITableViewControllerは、iPhoneのフレームワークUIKitに定義されている、Tableを操作するためのオブジェクトです。

かわって右辺では、UITableViewControllerのインスタンス生成と初期化を行っています。
Objective-Cでは、メソッドの呼び出しを[]で囲んだ中で行います。ここで[UITableViewController alloc]と書いてあるのはUITableViewControllerクラスのallocメソッドを呼び出していることになります。
(なお、メソッド呼び出しをメッセージと呼んだりする、とかsmalltalkに影響を受けたObjective-Cならではの話もありますが、ここではその辺は割愛します。)

また、[]が2重になって呼び出しを行っていますが、これはallocの返り値に対してそのまま次のメソッド呼び出しをしているためです。
allocメソッドはUITableViewControllerのインスタンス生成を行い、そのオブジェクトを返しますが、実際にはこれはメモリ領域を確保した、程度のものにすぎません。
これをiPhoneフレームワーク内で利用するには初期化をする必要があります。

その初期化を行っているのがその後のinitWithStyleメソッドで、このように初期化を行うメソッドをイニシャライザと呼びます。
各クラスにはほぼ必ずイニシャライザが定義されており、initもしくはinitHogehogeといった名前で何らかの初期化メソッドがあります。


このallocによるインスタンス生成とイニシャライザの使用は、二つセットで一つだと思っておいてください。
(なお、中には、インスタンス生成とイニシャライズを同時に行ってくれるメソッドを持っているものもあります。が、またそれは次の機会に。)


ちなみに、メソッド名に続けて:(コロン)で付与されているのは、このメソッドに渡す引数です。
ここでは、initWithStyleメソッドに対して、UITableViewStylePlainという定数を渡しています。
このinitWithStyleメソッドはテーブルのstyleを定義するメソッドで、UITableViewStylePlainという定数を渡すことでこのテーブルをPlainなスタイルで表示する、ということを指定しています。


このような処理のもと、tableViewControllerという変数にUITableViewControllerオブジェクトが格納されます。

2行目の処理

2行目ですが、こちらは単純です。
  1. [window addSubview:tableViewController.view];
既にメソッドの呼び出しと引数渡しについては解説したので、だいたいのところはわかると思います。
windowという変数は、このsamplePrjAppDelegateクラスが持っているメンバ変数で、UIWindowというiPhoneのウィンドウを形作るオブジェクトが格納されています。
この辺りは、ヘッダー等について詳しく説明する際にあわせてお話しします。

window変数に格納されているUIWindowオブジェクトのaddSubviewメソッドを呼び出して、ウィンドウの中にテーブルのviewを渡しています。

ここで、変数tableViewControllerに.(ピリオド)でつなげてviewというのを記述しています。
これは、tableViewControllerオブジェクトが内部に持っているメンバ変数viewを(実際にはメンバ変数viewのgetterを)呼び出しています。

こうして、テーブルを操作するUITableViewControllerが保持しているテーブルのViewを、iPhoneの表示側であるUIWindow内にsubviewとして渡すことで、上でビルドしたようにテーブルが表示されるようになります。


今回のまとめ

というわけで、ものすごーく基礎からの解説でしたが、どうでしょうか。

今回は、
1.基本的な呼び出しの流れ
2.テーブルの表示
3.メソッドやメンバ変数の呼び出しとか
あたりについてざっくりと説明しました。
最初はちょっと簡単すぎましたね。。。
でもどんどん長くなっちゃうので、ひとまずこの辺で><

多くのチュートリアルだとこのテーブル表示はIBでやってしまうことがほとんどですが、こんな感じで完全にプログラマブルな感じで生成していくことも可能です。


どのくらいこの手の話の需要があるかもわからないんで、なんか需要があるようだったら続き書いていくつもりです。
次回続いたら、テーブルを拡張/カスタマイズしていく方法とかについて書こうと思います。

コメント

    • 私もド素人なもので、とても参考になりました!
      是非続きをお願いします!!
    • >Stringさん
      ありがとうございます><
      頑張って続き書いていきます!
    • とてもわかりやすかったです。
      続編も期待しております!
    • とても分かりやすいです。
      続編をどうかお願いします!
    • >たかさん
      >げげげさん
      ありがとうございます!
      なかなか時間取れてないのですが、鋭意作成中です><
    • すばらしいブログですね。
      ど素人のiPhoneプログラマーです。
      毎日、拝見いたします。

      (複数のTextFieldを作成して、そこに入力された情報を得て、TextView(多分?)で表示したいと思っています。Appleからsample codeで提供されているUICatalogを見てもよく判らないので、こんな辺りを書いていただけるととても嬉しいです。)

      私も続編を期待しています。
    • CとPHPを習得しても、Objective-Cにつまずいた者です。。。

      IB抜きの方がとても分かりやすく、
      腹にすっと落ちてきました。

      続編を心から期待しております。
      がんばってください!!
    • とても参考になりました。
      続編期待しております。
    • めちゃくちゃ参考になります。
      ずっと前に進めないでいたので、本当に助かりました!
      ありがとうございました!
    • いきなりメモリリークしてませんか?
      [tableViewController release];
      が必要かと。
    • > やすさん
      ご意見ありがとうございます。
      進みが遅くて済みません><
      参考にします。

      > ピエロさん
      > 通りすがりさん
      > 通りすがり2さん
      このくらいの事でそう言って頂けて、ありがとうございます><
      のんびりペースですが、進めていけたらと思います。

      > 通りすがりさん
      ご指摘の通り、メモリリークがあります。
      第1回のほうでその事を書いていないため、意図がわかりにくくなって済みません。
      第2回以降の方で書いていますが、このリークは後の説明のために意図的にやっています。

      このプログラムでそのまま
      [tableViewController release]
      としてはいけません。
      Controllerがどこにも保持されなくなってしまいます。
      そのため、メンバ変数を定義し、そこに保持する必要があります。
    • すいません。iPhoneアプリ開発初心者です。
      なので教えてほしいのですが、
      今苦戦しているのは別クラスからの画像の処理です。
      +drawImageというクラスに画像名を飛ばしそこにあるImageやViewを使って
      表示させたいのですが、状態としては警告が出ます。
      警告文的にはaddSubviewが+addSubviewが何たら・・・
      と言われます。

      なので[??? addSubView];←ここに何を入れれば良いのかが判りません。
      drawImageが入ってるのはGdrivControllerです。
      これをMainViewとして使ってます。
    • perl、javascript、phpあたりのスクリプト言語しかできないものです。
      とにかく
      めっちゃ参考になりました。
      続きが読みたくてしょうがないです。
    • いまさらiPhoneアプリなんです。。。
      で、Object-Cもよくわからないのに。。。
      そして、SDKをDLして入門書とか読んで試していたのですが、そもそもObject-C構文とかの前に、Interface Builder(IB)での関連付けがわけわかんね!!
      と思っていてココを見つけました。
      こういった形で説明してくれたほうがよっぽど解る!!
      ありがとうございます。
      本買って損したな。
    • あざーっす。
      とても読みやすいっす。
    • 初心者です。
      わかりやすくて、とても良い文書です。
    • 動きが全くわからなくて、すごく困っていたので、この記事を見つけたときは本当に感激しました。この数週間、ずっと調べても調べても流れがわからずじまいで、どうしようかと思っていたのですが >< もっと早くに見つけていれば〜〜!と思いますが、とにかくありがとうございます。今後もちょくちょく見に来ます。

コメントフォーム

認証
captcha_key
 

トラックバック