チュートリアル:Hello World!

2010. 04. 29
今更な感もありますが、(リハビリも兼ねて)一応説明します。

iPhone SDKプログラミング大全』のHello Worldプログラムは極シンプルで、以下のような特徴があります。

・テンプレートは『View-based Application』ではなく『Window-based Application』を使う
・アウトレットのLabelとアクションのRound Rect Buttonを一つずつ
・ラベルは初期値は空で、ボタンを押すとテキストを表示
(テキストをクリアするルーチンは無いので、2回目以降のボタン押下では見た目上変化無し)


●プロジェクトの作成

225

Xcodeを起動し、『Window-based Application』を選択、プロジェクト名を『HelloWorld』とします。

226


●HelloWorldAppDelegate.hの編集

View-basedですと~ViewController.hを編集するのですが、Window-basedの場合は~ViewControllerは作られませんので、~AppDelegateを編集することになります。

アウトレットとアクションを追加し、保存します。

@interface HelloWorldAppDelegate : NSObject <UIApplicationDelegate> {
    UIWindow *window;
    // アウトレットの追加
    IBOutlet UILabel *label;
}

@property (nonatomic, retain) IBOutlet UIWindow *window;

// アクションの追加
- (IBAction)sayHello;

@end

231


●ユーザインターフェイスのレイアウト

ソースファイル同様、Window-basedでは~ViewController.xibというnibファイルはありませんので、MainWindow.xibをダブルクリックしてInterface Builderを立ち上げて編集します。

227

中央付近にLabelを置き、Textをクリアします。

その下にRound Rect Buttonを置き、Titleを『Say Hello』とします。


●アウトレットとアクションの接続

232

View-basedでは『File's Owner』でしたが、Window-basedの場合は『Hello World App Delegate』を右クリックしてConnectionsパネルを開きます。

228

OutletsのlabelをLabelに接続、Received ActionsのsayHelloをRound Rect Buttonに接続して『Touch Up Inside』を選択します。

編集が終わったらファイルを保存します。


●HelloWorldAppDelegate.mの編集

最後に@implementation HelloWorldAppDelegateの下にアクションのメソッドを記述します。

- (IBAction)sayHello{
    label.text = @"BRAND NEW TOUCH 始めよう SAY \"HELLO!!\"";
}

229

文字列を指定する際には""(ダブルクォーテーション)で囲みますが、ダブルクォーテーションを表示させるにはどうするのか悩んだのは秘密です。
(Unicodeの直接指定『\u0022』ではコンパイル時にエラーが出ます。理由は不明)


●ビルドと実行

230

実行すると、最初はボタンだけが表示され、ボタンを押すと文字列が表示されます。

今までのView-basedと操作するファイルが異なりましたが、基本的には変わりません。



参考文献

WindomSoft/プログラミング/C言語入門/C言語の基礎

iPhone SDK 3 プログラミング大全 実践プログラミング (MacPeople Books)iPhone SDK 3 プログラミング大全 実践プログラミング (MacPeople Books)
(2009/09/08)
木下 誠

商品詳細を見る

テーブル(1)

2010. 04. 25
iPhone SDKプログラミング大全』では、Hello Worldを表示するサンプルコードの作成の順番なのですが、Macが入院中なのでその次のテーブルの話をします。


●UITableView、UITableViewCellクラスの継承階層

UITableViewの継承階層は次のようになっています。
(UIKit全体図は『UIKitの概要』を参照してください)

NSObject
    ∟UIResponder
            ∟UIView
                    ∟UITableViewCell
                    ∟UIScrollView
                            ∟UITableView


●UITableViewの概要

UITableViewのインスタンス(または単にテーブルビューと呼ぶ)は、情報を階層化したリストの表示と編集を行います。

UIKitフレームワークのテーブルビューは、デバイスの小さな画面に対応するために表示が一列に制限されています。

UITableViewはUIScrollViewのサブクラスなのでテーブルをスクロールすることができますが、UITableViewでは垂直方向のスクロールしかできません。

テーブルはUITableViewCellオブジェクトのセルによって構成されており、UITableViewはこれらのオブジェクトを使用してテーブルの行を描画します。

セルはタイトルとイメージを持つことができ、また右端付近にアクセサリビューを表示できます。

標準アクセサリビューには、ディスクロージャインジケータ(次のレベルのデータ階層に進む表示)や詳細ディスクロージャボタン(選択したアイテムの詳細を表示するボタン)があります。

アクセサリビューは、スイッチやスライダなどの制御系フレームワークやカスタマイズしたビューを使用できます。

テーブルビューには編集モードが有り、ユーザがテーブルの行の挿入、削除、並べ替えなどが行えます。

テーブルビューは0個以上のセクションを持ち、それぞれ独自の行を持ちます。

セクションはテーブルビュー内でインデックス番号で識別され、行はセクション内でインデックス番号で識別されます。

セクションは、先頭にセクションヘッダを最後にセクションフッタを任意に設定できます。

テーブルビューにはUITableViewStylePlainとUITableViewStyleGroupedの2つのスタイルが有ります。

UITableViewのインスタンスを生成する際にはスタイルを指定する必要が有り、またスタイルは変更することができません。

233

プレーンスタイルでは、セクションヘッダとフッタを、全てのセクションより上に浮いた形で表示できます。

テーブルビューは右側に(例えば『a』~『z』などの)インデックスバーを表示させることができ、特定のラベルをタッチすると目的のセクションにジャンプできます。

234

テーブルビューのグループスタイルは、全てのセルに対しデフォルトで背景色と背景ビューを提供します。

背景ビューは、セクション毎に全てのセルを視覚的にグループ化して提供します。
(例えば、あるグループは個人名とタイトル、別のグループには電話番号、別のグループにはメールアカウントなど)

グループテーブルの例についてはアプリケーションの設定を参照してください。

グループスタイルのテーブルビューはインデックスを持つことはできません。

UITableViewの多くのメソッドは、NSIndexPathのオブジェクトをパラメータや戻り値として持っています。

UITableViewは、NSIndexPathで表現された行インデックス(rowプロパティ)とセクションインデックス(セクションプロパティ)、そして指定した行インデックスとセクションインデックス(indexPathForRow:inSection:メソッド)から組み立てたインデックスパスを宣言します。

特に複数のセクションを持つテーブルビューでは、行のインデックス番号を確認する前に、セクションインデックスの数を求める必要があります。

UITableViewオブジェクトは、データソースとなるオブジェクトとデリゲートとなるオブジェクトを持つ必要があります。
(通常はアプリケーションデリゲート、もしくはカスタマイズされたUITableViewControllerオブジェクトです)

データソースは、UITableViewDataSourceプロトコルと、UITableViewDelegateプロトコルのデリゲートを採用している必要があります。

データソースは、テーブルの行を挿入、削除、並べ替えなどのデータモデルを管理し、UITableViewがテーブルを構築するのに必要な情報を提供します。

デリゲートは、テーブルで使用されるセルの提供と、他のタスク(アクセサリビューとセレクションの管理など)を提供します。

(第1引数がYESの)setEditing:animated:メッセージが送られるとテーブルビューは編集モードになり、編集または並べ替えという操作に応じたUITableViewCellのeditingStyleで行を表示します。

挿入や削除を選択すると、データソースはtableView:commitEditingStyle:forRowAtIndexPath:メッセージを受信します。

削除の場合はdeleteRowsAtIndexPaths:withRowAnimation:を、挿入の場合はinsertRowsAtIndexPaths:withRowAnimation:で委託します。

また編集モードで、テーブルビューのセルがshowsReorderControlプロパティがYESの場合、データソースはtableView:moveRowAtIndexPath:toIndexPath:メッセージを受信します。

データソースは、tableView:canMoveRowAtIndexPath:でセルの削除や並べ替えを行うことができます。

UITableViewのキャッシュはテーブルビューセルの表示されている行のみですが、テーブル全体の行とヘッダ、フッタもキャッシュされています。

デフォルトセルと異なる行動特性を持った、カスタムUITableViewCellオブジェクトを作ることもできます。
iOS Table Viewプログラミングガイドの『Table View Cellの詳細』を参照してください)

UITableViewは、UITableViewの新しいインスタンスを生成する、または新しいデータソースを割り当てる場合のみreloadDataを呼び出し、UIViewのlayoutSubviewsメソッドをオーバーライドします。

テーブルビューをリロードすると、現在の選択を含む状態をクリアします。

しかし明示的にreloadDataを呼び出した場合は、状態のクリアとその後の直接または間接的なlayoutSubviewsの呼び出しによるリロードは行われません。


●テーブルビュースタイル

テーブルビューのスタイルはプレーンとグループの2種類有り、UITableView.hで定義されています。

テーブルスタイルを設定する際には、テーブルビューを初期化してください。
(initWithFrame:style:参照)

スタイルは後で変更ができません。

typedef enum {
    UITableViewStylePlain,
    UITableViewStyleGrouped
} UITableViewStyle;

・UITableViewStylePlain

簡素なテーブルビュー。
全てのセクションのヘッダまたはフッタはインラインセパレータで表示され、テーブルビューがスクロールする際には浮いた表現になります。

・UITableViewStyleGrouped

セクション毎に別個の行のグループとなるテーブルビューです。
セクションのヘッダとフッタは浮いていなく、行と一緒にスクロールします。


●セクションインデックスアイコン

テーブルビューにセクションインデックスのアイコンを表示させます。

UIKIT_EXTERN NSString *const UITableViewIndexSearch;

UITableIndexSearch:sectionIndexTitlesForTableView:で返される文字列の配列の中に、この文字定数が含まれていた場合、セクションインデックスは拡大鏡のアイコンと一致するインデックスの位置を表示します。

この位置は、一般的にインデックスの最初のタイトルの場所になります。



参考文献

UITableView Class Reference

UITableViewDataSource Protocol Reference

UITableViewCell Class Reference

iOS Table Viewプログラミングガイド

福井高専IT研究会OfficialWiki/UITableView

iPhone SDK 3 プログラミング大全 実践プログラミング (MacPeople Books)iPhone SDK 3 プログラミング大全 実践プログラミング (MacPeople Books)
(2009/09/08)
木下 誠

商品詳細を見る

ターゲット/アクションモデル

2010. 04. 24
●ターゲット/アクションモデル

UIKitの概要』で軽く触れている『ターゲット/アクションモデル』について、少し掘り下げたいと思います。
(『Cocoa Fundamentals Guide』では『ターゲット/アクションメカニズム』と呼んでいます)

UIKitの概要では、

『ユーザとアプリケーションの対話において、ユーザが画面をタップするなど操作をすると、コントロールがアクションメッセージとして、それに対応するオブジェクト(ターゲット)に送信します』

と書きましたが、分かり易くすると、

タップなどのユーザの操作

iPhone OSが操作をイベントとしてアプリケーションへ送信

アプリケーションがイベント発生位置のビューへ送信

ビューが受け取ったイベントを処理 → ビュー自身が処理(ボタンの反転処理など)

ビューが処理しないイベントを適切なコントローラへ送信

コントローラが『指定されたオブジェクト(ターゲット)』へ『メッセージを送信(アクション)

『メッセージを送信』=『メソッドの呼び出し』なので、特に難しい話をしているわけではないことが分かります。

iPhone SDKプログラミング大全』の本文中では、ビューがターゲット(コントローラ)とアクションを指示しているような図になっていますが、ちょっと解釈が違うと思われます。

ここでは『iOSアプリケーションプログラミングガイド』の記述にあるように、コントローラがターゲットにアクションを指示するものとします。
(そうでなければMVCの概念とも矛盾するような感じですので・・・)

●ターゲット

ターゲットはアクション(メッセージ)を受信するオブジェクトで、MVCのモデルに相当するとともに、InterfaceBuilderで設定するアウトレット(IBOutlet)に該当します。

●アクション

アクションはコントロールがターゲットに送信するメッセージで、InterfaceBuilderで設定するアクション(IBAction)に該当します。

●アクションメソッド

アクションとなるメソッドは、Mac OS XのAppKitの場合1種類ですが、iPhone OSのUIKitは3種類あります。

- (void)action
- (void)action:(id)sender
- (void)action:(id)sender forEvent:(UIEvent *)event

senderは送信側のオブジェクトを指定し、eventはどのようなイベントで呼び出されたかを指します。

また、コントローラは同じアクションを複数のターゲットを割り当てたり、一つのコントローラが複数のターゲットに異なるアクションを送信することもできます。



参考文献

iOSアプリケーションプログラミングガイド

Cocoa Fundamentals Guide

UIControl Class Reference

iPhone SDK 3 プログラミング大全 実践プログラミング (MacPeople Books)iPhone SDK 3 プログラミング大全 実践プログラミング (MacPeople Books)
(2009/09/08)
木下 誠

商品詳細を見る

MVCアーキテクチャ

2010. 04. 23
MVC(Model View Controller)アーキテクチャ(デザインパターンとも呼ばれます)は、特にGUIアプリケーションの製作において有効とされるソフトウェアの設計・実装手法です。

アプリケーションの設計において、構成要素をモデル(Model)、ビュー(View)、コントローラ(Controller)という3つの機能に分けることにより、機能の明確化と独立性、移植性を高めるものです。

モデルはデータおよびデータの処理を受け持ち、ビューは画面を構成し入出力を受け付け、コントローラはモデルとビューの間を取り成します。

 ユーザの入力 データの更新要請 

ビュー
(View)

コントローラ
(Controller)

モデル
(Model)

 画面への出力 データの更新通知 



参考文献

iOS Table Viewプログラミングガイド

iOS View Controllerプログラミングガイド

iOSアプリケーションプログラミングガイド

Wikipedia/Model View Controller

IT用語辞典/MVC

iPhone SDK 3 プログラミング大全 実践プログラミング (MacPeople Books)iPhone SDK 3 プログラミング大全 実践プログラミング (MacPeople Books)
(2009/09/08)
木下 誠

商品詳細を見る

アプリケーションのライフサイクル(3)

2010. 04. 18
イベントループの話をするために『アプリケーションのライフサイクル(1)』という所から始めたんですが、ことイベントループそのものが何処でどう動いているのか判然としていなく、明瞭な説明ができないことを先にお詫びいたします。

3)イベントループ(イベント処理サイクル)

前回の『アプリケーションのライフサイクル(2)』おさらいをしますと、

main()関数の呼び出し
元がC言語なので、最初に読み込まれるのがmain()関数なのは理解できる。



UIApplicationMain()関数の呼び出し
UIApplicationのインスタンスとデリゲートを生成。
第3引数でUIApplicationのインスタンス、第4引数でデリゲートの指定をしている。



アプリケーションデリゲートの作成
システムイベントにデリゲートが応答する

と、ここまで書いて『どこでイベントループを作っているんだろう』とあれこれ調べましたが皆目検討がつかず、UIApplicationMain()関数の内部で作っていて、表に見えていないんだろうと思うことにしました。
(合っているかどうかは分かりませんが)

この辺りはテンプレートを使えば自動生成される部分でもあり、特にmain()関数は手を加えることもあまり無いので、目に見える部分に気を配れば中身は概念さえ抑えておけばいいということなのかもしれません。

iOSアプリケーションプログラミングガイド』の『イベント処理サイクル』の話を解説しようかとも思いましたが、途中からよく分からなくなるので諦めました。
(プロセスとかスレッドとか出てくる辺りから意味不明)

仕方ないので一般的なイベントループの概念だけでも紹介します。


・イベントループの概念

まず『イベント駆動(イベントドリブン)』の話から。

ここで言うイベントとは、『画面をタッチした』『デバイスを回転させた』などのユーザが行う行為や、『電話がかかってきた』などのシステムからの通知も含めた、プログラムに対するメッセージのことです。

イベントの発生(トリガ)によるメッセージをプログラムが受けて応答することをイベント駆動と言います。

プログラムはイベントが発生するまでは待機状態で(表向きは)何もしませんが、常にイベントを受け取る準備をしており、イベントを受けたら応答してまた待機するということを繰り返します。
これをイベントループと呼びます。

イベントはまずOSが受け取り、一旦イベントキューに置かれ、アプリケーションに渡されます。

イベントキューとは待機場のことで、アプリケーションがイベントを処理して待機状態に戻るまでのバッファの役割を果たします。

複数のイベントが連続して発生した場合、アプリケーション側はイベントキューから並べられた順番にイベントを取り出して処理します。

iPhone OSの場合、イベントはUIApplicationMainオブジェクトのイベントループに渡されます。

UIApplicationMainオブジェクトはデリゲートと協調し、受け取ったイベントを適切なオブジェクトに処理させます。

以上、(それくらいなら誰でも知っている)イベントループの話でした。

オマケとして、何か手掛かりがあるかと思って訳したUIApplicationクラスの概要を、せっかくなので載せておきます。

・UIApplicationクラスの概要

UIApplicationクラスはiPhone OSで実行するアプリケーションの制御と調整を集中管理するものです。

全てのアプリケーションは必ずUIApplication(もしくはUIApplicationのサブクラス)のインスタンスを持ちます。

アプリケーションが起動するとUIApplicationMain関数が呼び出され、シングルトンのUIApplicationオブジェクトを作成します。

その後、sharedApplicationクラスメソッドで、このオブジェクトにアクセスできるようになります。

UIApplicationオブジェクトの主な役割は、ユーザからのイベントを最初に受け取ることです。

そしてコントロールオブジェクト(UIControl)により、適切なターゲットオブジェクトへアクションメッセージを送ります。

さらにUIApplicationオブジェクトは、アプリケーションが現在開いている全ウィンドウ(UIWindowオブジェクト)のリストを保持し、そこからアプリケーションのUIViewオブジェクトを取得します。

アプリケーションオブジェクトは通常デリゲートを割り当て、アプリケーションに重要なランタイムイベント(例えばアプリケーションの起動、メモリ不足の警告、アプリケーションの終了)を適宜知らせ、応答できる機会を与えてくれます。

アプリケーションは、openURL:メソッドで送られたメールやイメージファイルなどのリソースを協調処理できます。

例えばアプリケーションがメールのURLを開くと、このメソッドがメールクライアントを起動しメッセージを表示することができます。

iPhone OS 3.0では、リモート通知の登録、アンドゥーリドゥ(取り消しーやり直し)UI(applicationSupportsShakeToEdit)、インストールされたアプリケーションがURLを開けるかどうか決定する(canOpenURL:)などがUIApplicationのメソッドに追加されています。

UIApplicationは、一つ以上のメソッドを実行する、UIApplicationDelegateプロトコルを採用したデリゲートを定義します。

UIApplicationとUIApplicationDelegateのインターフェイスにより、デバイス固有の動作を管理することができます。

これにより、デバイスの向きによってインターフェイスの方向を変えたり、ユーザイベントを一時的に保留したり、近接センサーにより画面のオン/オフしたり、アプリケーションの応答を制御できます。

サブクラス化の注意

カスタムイベントとアクションディスパッチを実装する場合は、UIApplicationのサブクラスであるsendEvent:またはsendAction:to:from:forEvent:をオーバーライドしてください。



参考文献

iOSアプリケーションプログラミングガイド

UIApplication Class Reference

福井高専IT研究会OfficialWiki/UIApplication

Wikipedia/イベント駆動型プログラミング

Wikipedia/イベント(プログラミング)

iPhone SDK 3 プログラミング大全 実践プログラミング (MacPeople Books)iPhone SDK 3 プログラミング大全 実践プログラミング (MacPeople Books)
(2009/09/08)
木下 誠

商品詳細を見る

アプリケーションのライフサイクル(2)

2010. 04. 17
いつにも増して英文和訳が怪しいので、鵜呑みにすると危険です。
(特にデリゲート関係は自分で書いていてよく分からない文章になっています)

2)main()関数の呼び出し

main()関数は、アプリケーション起動時に最初に読み込まれるOther Sourcesフォルダ内のmain.mファイルに記述されていて、アプリケーションの初期化を行います。

220

2-1)UIKitフレームワークのインポート

2-2)main()関数の引数

2-3)自動解放プールの作成と解放

2-4)UIApplicationMain()関数の呼び出し

2-5)アプリケーションデリゲートの作成

2-6)UIApplicationDelegateプロトコル

2-7)~AppDelegateの宣言と実装

#import  <UIKit/UIKit.h>

int main(int argc, char *argv[]) {

    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    int retVal = UIApplicationMain(argc, argv, nil, nil);
    [pool release];
    return retVal;
}


2-1)UIKitフレームワークのインポート

まず1行目で『すべてのiPhoneアプリケーションは、UIKitフレームワークを使用して作成されます』の言葉通り、UIKit.hがインポートされています。


2-2)main()関数の引数

main()関数の引数argcとargvは、コマンドライン引数と呼ばれるもので、コマンドラインからmain()関数を呼び出す際に引数を渡すことができるというC言語の仕様です。
(UIApplicationMainに渡してるので、何を意味しているのかとUIApplicationMain関連を30分も調べていたのは内緒です。どうりで誰も説明しないわけですね)

現実問題として、iPhoneアプリケーションをコマンドラインから呼び出すことは普通しないので無視していいと思います。
(わざわざUIApplicationMainに渡しているということは何か使い道があるとは思いますが)


2-3)自動解放プールの作成と解放

NSAutoreleasePoolは自動解放プールを作るメソッドです。

自動解放については『Objective-C言語のメモ書き(7)』でも説明していますが、軽く紹介します。

プログラムの中で、一時的に利用してすぐ不要になるインスタンスがよくありますが、不要になった後に解放し忘れるとメモリを確保し続け、いわゆるメモリリークの状態になります。

適宜解放すればいい話ではありますが手間がかかりますし、解放し忘れることもあります。

その煩雑さを解消するのが自動解放で、自動解放用に登録されたインスタンスを待機場(プール)に集めておき、後でまとめて解放しようというものです。

インスタンスの生成/初期化時に『autorelease』というフラグを立てることによって登録されるので、一時利用のインスタンスが多数ある場合には一つ一つ解放する手間が省けることになります。

ただしretainでリファレンスカウンタ(参照カウンタ)を増やした場合は、当然解放する回数を合わせなければなりません。

また、テンプレートで作ったプロジェクトではmain()関数に自動解放プールが設定されるものの、このデフォルトの状態ではアプリケーション終了時にまとめて解放することになるので、大量に登録するとメモリが足りなくなるので注意が必要です。
(大量に使用する場所には、別途自動解放プールを設定した方がいいでしょう)

※2010.4.17訂正
24/7 twenty-four seven/autoreleaseされたオブジェクトはいつ解放されるか』によりますと、
 
NSAutoreleasePoolはイベントループが一周するたびに生成と破棄を繰り返します。ですので、アプリケーション終了まで、オブジェクトが溜まっていくということはありません。たいていは、autorelease済みのオブジェクトはメソッドを抜けた後に解放されます。

ということでした。お詫びして訂正させていただきます。

詳細を知りたい方は、『高度なメモリ管理プログラミングガイド』に難解な説明がありますので参照してください。

実際のmain()関数では

NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

でNSAutoreleasePoolのインスタンス『pool』を生成/初期化、つまりプールを設置し、

[pool release];

でプールを解放します。


2-4)UIApplicationMain()関数の呼び出し

実際にアプリケーションの初期化を行うのがUIApplicationMain()関数で、UIApplicationのインスタンスを生成します。


UIApplicationMain

int UIApplicationMain (
    int argc,
    char *argv[],
    NSString *principalClassName,
    NSString *delegateClassName
);

main()関数が呼び出す、アプリケーションオブジェクトとアプリケーションデリゲートの生成、アプリケーションの実行ループを含むイベントループの設定を行う関数です

戻り値はint型(整数)を指定していますが、この関数は戻り値を返しません

ユーザがホームボタンを押してiPhoneアプリケーションを終了させた時、0の引数と終了システム関数を呼び、アプリケーションはすぐに終了します

アプリケーションのInfo.plistファイルで、NSMainNibFileキーに対応するnibファイルが設定されていれば、このnibファイルを読み込みます

argc:第2引数argvの項目数を指定します
通常はmain()関数から引き継ぎます

argv:引数の配列を指定します
通常はmain()関数から引き継ぎます

principalClassName:UIApplicationクラスまたはサブクラスの名前を指定します
nilの場合はUIApplicationとなります

delegateClassName:アプリケーションデリゲートをインスタンス化するクラス名を指定します
principalClassNameでUIApplicationのサブクラスを指定した場合、サブクラスのデリゲートを指定する必要が有ります
nilの場合は、アプリケーションのメインnibファイルからデリゲートオブジェクトを読み込みます


デフォルトでは第3、第4引数ともにnilが指定されていますので、UIApplicationクラスでアプリケーションオブジェクトが、第4引数でInfo.plistの『Main nib file base name』に設定されているnibファイル

222

この場合MainWindow.xibファイルで設定されていますので、開いてみると

221

Untitled App Delegateというデリゲートが作られていることになります。


2-5)アプリケーションデリゲートの作成

当サイトでも何度か取り上げつつ理解していないデリゲートですが、そろそろ覚えたいので説明してみます。

デリゲートは日本語では代理、委託、委譲などと訳されるもので、メッセージを受けたオブジェクトが自分で処理できない、あるいは少し細工を加えて処理したい場合にデリゲートオブジェクトに処理を頼むという仕組みです。

自分で処理できないメッセージを託すのは、例えばボタンのオン/オフを表示するオブジェクトが操作の是非を判断する場合など、本業以外はデリゲートに任せ独立性を保持する意味があります。

少し細工を加えて処理するのも同様で、自分が持っていない機能の指示を一緒に渡して処理してもらうことで、複雑なオブジェクトのサブクラス化を避ける意味があります。

デリゲートは開発者が任意の位置に配置できますが、UIApplicationMain()関数で設定されるアプリケーション固有のデリゲートをアプリケーションデリゲートと言います。

アプリケーションデリゲートは全てのアプリケーションに必須ですが、テンプレートでプロジェクトを作成すると自動で~AppDelegate.mと~AppDelegate.hが作られます。 

(正確には上記のようにMainWindow.xibファイルで登録されている~App Delegateがアプリケーションデリゲートとなります)

この中にアプリケーションの初期実行状態にする準備と、終了時に未保存データやアプリケーションの状態を保存する処理などを記述します。

アプリケーションデリゲートのオブジェクトはUIApplicationDelegateプロトコルを採用している必要が有ります。


2-6)UIApplicationDelegateプロトコル

UIApplicationDelegateプロトコルは、シングルトンのUIApplicationオブジェクトのデリゲートを宣言するメソッドです。
(シングルトンはインスタンスを一つしか作らないクラスのことで、何処で何回呼ばれても同じインスタンスを返します)

このメソッドを実行すると、アプリケーションの起動と終了、メモリ不足の警告、URLリソースを開く、ステータスバーの向きの変更などシステムイベントにデリゲートが応答できるようになります。

iPhone OS 3.0では、リモート通知関連のメソッドやapplication:didFinishLaunchingWithOptions:を追加しました。

application:didFinishLaunchingWithOptions:メソッドはapplicationDidFinishLaunching:の代わりに呼び出すことができます。

これらの新しいメソッドは次の二つの状況を想定しています。

・iPhone OSがアプリケーションにリモート通知を配信し、ユーザがその通知に応答して起動する
・UIApplicationのopenURL:メソッドで、URLのスキーム(リソースを取得する手段)からリソースタイプを判別して他のアプリケーションを起動する

通常の場合は起動する理由が異なるので、別のユーザインターフェイスでアプリケーションを選択します。

UIApplicationは、application:didFinishLaunchingWithOptions:のオプションで指定されている辞書(NSDictionaryオブジェクト)を渡します。

アプリケーションを起動する要因となる辞書には二つ有り、一つはopenURL:メソッドを呼び出したアプリケーションのバンドルID(バンドル識別子)かURLオブジェクトを含む辞書、もう一つはリモート通知に含まれるペイロードの辞書です。

このメソッドがデリゲートを作る場合、起動時に以下の順序で呼び出されます

application:didFinishLaunchingWithOptions:
applicationDidBecomeActive:

代替として

applicationDidFinishLaunching:
applicationDidBecomeActive:
application:handleOpenURL:(アプリケーションの起動にURLが使われている場合)

同様に、プッシュ通知を受けてアプリケーションを起動させる際に、application:didFinishLaunchingWithOptions:メソッドとapplication:didReceiveRemoteNotification:メソッドの両方を実装すると、後者のメソッドは実行されません。

双方の場所でリモート通知を処理する必要があります。


2-7)~AppDelegateの宣言と実装

Window-based ApplicationのUntitledというプロジェクトを例に、アプリケーションデリゲートの内容を見てみます。


・UntitledAppDelegate.h

224

// UIKitフレームワークのインポート
#import <UIKit/UIKit.h>

// UntitledAppDelegateのクラス宣言(UIApplicationDelegateプロトコルの採用)
@interface UntitledAppDelegate : NSObject <UIApplicationDelegate> {

// このアプリケーションで使うウィンドウのインスタンス変数の宣言
    UIWindow *window;
}

// ウィンドウのインスタンス変数のプロパティを宣言
@property (nonatomic, retain) IBOutlet UIWindow *window;

@end

@interfaceでUntitledAppDelegateのクラス宣言しています。

スーパークラスはNSObjectですが、UIApplicationDelegateプロトコルを採用しなければならいので<>で追加しています。
(『Objective-C言語のメモ書き(4)』参照)

プロパティの属性はnonatomic(非同期)、retain(値を保持して変更)。

IBOutletはInterface Builderへ接続するためのキーワードで、アウトレットとして扱うことを指します。
(『Objective-C言語のメモ書き(5)』参照)


・UntitledAppDelegate.m

223

// ヘッダファイルの読み込み
#import "UntitledAppDelegate.h"

// ヘッダファイルで宣言した、UntitledAppDelegateクラスの実装
@implementation UntitledAppDelegate

// ヘッダファイルで宣言した、windowプロパティの実装
@synthesize window;

// アプリケーション起動直後の処理
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    // Override point for customization after application launch
    // アプリケーション起動後にカスタマイズする場合、上書きする内容を記述する

    // ウィンドウの表示
    [window makeKeyAndVisible];

    return YES;
}

- (void)dealloc {

    // ウィンドウオブジェクトの解放
    [window release];

    // スーパークラス(NSObject)の解放
    [super dealloc];
}

※ deallocインスタンスメソッドについては、後日理解した際に説明したいと思います。


・application:didFinishLaunchingWithOptions:

- (BOOL)application:(UIApplication *)applicationdidFinishLaunchingWithOptions:(NSDictionary *)launchOptions

リモート通知やURLリソースを開くことにより、アプリケーションが起動することをデリゲートに伝えます

アプリケーションがURLリソースを処理できなかった場合はNO、処理できた場合はYESを返します。

リモート通知の結果によってアプリケーションが起動した場合は、この戻り値は無視されます。

(次の文は上手く訳せなかったので原文を転載します)
Objects that are not the application delegate can access the same launchOptions dictionary values by observing the notification named UIApplicationDidFinishLaunchingNotification and accessing the notification’s userInfo dictionary.

applicationDidFinishLaunchingの代わりに、このメソッドを使用することを推奨します。
(2つの解説を見比べて下さい)

application:デリゲートするアプリケーションオブジェクト指定します

launchOptions:次の2つの状況に関連する情報を含む辞書を指定します

・iPhone OSがアプリケーションにリモート通信を配信し、警告メッセージの表示を経てアプリケーションを起動する場合

・URLのリソースをスキームで判別し、他のアプリケーションを開く場合

前者の場合、launchOptionsの辞書は、通知ペイロードの辞書を含みます。
(詳細は『UIApplicationDelegate Protocol Reference/application:didReceiveRemoteNotification:』を参照)

後者の場合、launchOptionsの辞書は、URLの示すオブジェクトと、URLが開こうとしているアプリケーションのバンドル識別子を含みます。

この辞書は、ユーザがアプリケーションのアイコンをタップして起動した場合はnilになります。

詳細はUIApplication Class Referenceの『UserInfo Dictionary Keys』に、これらの辞書オブジェクトのキーやアクセス方法の説明があります。


・makeKeyAndVisible

- (void)makeKeyAndVisible

キーウィンドウを作成して描画します

これは便利なメソッドで、レシーバのメインウィンドウを作成し、他のウィンドウより前に表示します

UIViewプロパティのhiddenを使ってウィンドウを隠すこともできます



参考文献

iOSアプリケーションプログラミングガイド

高度なメモリ管理プログラミングガイド

LocalおよびPush Notificationプログラミングガイド

NSAutoreleasePool Class Reference

UIKit Function Reference

UIApplicationDelegate Protocol Reference

UIWindow Class Reference

サルにもできるiPhoneアプリの作り方Step2/Objective-C入門

初心者のためのポイント学習C言語/コマンドライン引数

Wikipedia/スキーム

IT用語辞典/ペイロード

iPhone SDK 3 プログラミング大全 実践プログラミング (MacPeople Books)iPhone SDK 3 プログラミング大全 実践プログラミング (MacPeople Books)
(2009/09/08)
木下 誠

商品詳細を見る

詳解 Objective-C 2.0 第3版詳解 Objective-C 2.0 第3版
(2011/12/28)
荻原 剛志

商品詳細を見る

アプリケーションのライフサイクル(1)

2010. 04. 16
iPhone SDKプログラミング大全』の本文中にさらっとイベントループの話が出てくるのですが、イベントループを説明するにはアプリケーション全体の流れを先に説明しないと理解し難いと思いますので説明します。

中身は『iOSアプリケーションプログラミングガイド』の劣化コピーのようなものなので、そちらを読んで理解できる方には不要な内容です。

アプリケーションのライフサイクル、つまり起動から終了までの一連の流れに関しては、『iPhoneアプリケーションプログラミングガイド』にまとめられているせいか、手元の本などでも説明されていません(見逃しているのかもしれませんが)。

本来ならばアプリケーションを作るにあたって最初に説明するような話なのですが、説明するにはそれなりの予備知識が必要になるので避けているのかもしれません。

実際、『iPhoneアプリケーションプログラミングガイド』も序章の時点で『iPhone OSでは、UIKitフレームワークを使用してネイティブアプリケーションを開発します』と言っている時点で、プログラミング初心者は置いてけぼりになるでしょう。

デリゲートやプロパティリストの話も出てきますし、その辺の説明を一通りした後で改めて取り上げるものでは無い、もしくは他の説明の中に組み込まれているからだと思われます。

以下の説明においても、過去当サイトで説明した事項に関しては、それを前提として話を進めたり、詳細を別ページに飛ばしたりしますのでご了承ください。


●アプリケーションのライフサイクル

アプリケーションのライフサイクル(起動から終了まで)は次のような手順になります。
(奇麗な図で見たい方は『iOSアプリケーションプログラミングガイド』をご覧下さい)

1)アプリケーションの起動

2)main()関数の呼び出し

3)UIApplicationMain()関数の呼び出し

3)イベントループ(イベント処理サイクル)

4)アプリケーション終了の問い合わせ

5)アプリケーションの終了

※2010.4.17修正
『3)UIApplicationMain()関数の呼び出し』を『2)main()関数の呼び出し』の中に組み込んでしまったので削除しました。


1)アプリケーションの起動

・ホーム画面でアプリケーションアイコンのタップ

iPhoneのホーム画面で、アプリケーションのアイコンをタップすることによってアプリケーションを起動します。

・トランジショングラフィックスの表示

アプリケーションの実際の起動画面を表示する間、画面中央からアプリケーションの画面が拡大するようなアニメーションが表示されます。
(トランジショングラフィックスの表示)

トランジショングラフィックスの画像はResourcesフォルダのDefault.pngが使われます。

Default.pngが無い場合は真っ黒な画面になります。
(ステータスバーがあると、アニメーションしていることが分かります)

Default.pngは(nibファイルを編集すること無く)Resourcesフォルダに入れるだけで適用されます。
(iPhone Simulatorで入れ替えたり削除して確認する際、消したはずの画像が出る場合は『ビルド』メニューの『クリーニング』を実行してください。iPhone Simulatorのリセットでは治りません)

Default.pngはあくまでトランジショングラフィックスの際の画像で、アニメーションが終わるとnibファイルで設定した背景画像(Background.png)になります。

背景画像を設定してなければWindowベースの場合は白、Viewベースだとグレイの画面になります。
(トランジショングラフィックスとは異なり、ResourcesフォルダにBackground.pngを入れただけでは反映されません。nibファイルで設定する必要があります)



参考文献

iOSアプリケーションプログラミングガイド

iPhone SDK 3 プログラミング大全 実践プログラミング (MacPeople Books)iPhone SDK 3 プログラミング大全 実践プログラミング (MacPeople Books)
(2009/09/08)
木下 誠

商品詳細を見る

UIKitの概要

2010. 04. 14
●UIKitの概要

UIKitフレームワークは、iPhoneとiPod touch、そしてiPadのアプリケーション・ユーザインターフェイスの構築と管理に必要なクラスを提供します。

アプリケーションのオブジェクト、イベントハンドリング、モデルの描画、ウィンドウ、ビュー、コントロールなど、タッチスクリーン用に最適化したインターフェイスのデザインを提供します。

核となる機能セットは以下の通りです。

・アプリケーション管理
・グラフィックスとウィンドウ処理のサポート
・タッチイベント処理のサポート
・ユーザインターフェイス管理
・標準的なシステムビューとコントロールを表すオブジェクト
・テキストおよびWebコンテンツのサポート
・URLスキームによるシステム上の他のアプリケーションとの統合
・加速度センサー
・内蔵カメラ
・ユーザのフォトライブラリ
・デバイス名およびモデル情報

UIKitフレームワークのクラス一覧表を以下に示します。

UIAcceleration
UIAccelerometer
UIAccessibilityElement
UIBarItemUIBarButtonItem
UITabBarItem
UIBezierPath
UIColor
UIDevice
UIDocumentInteractionController
UIEvent
UIFont
UIGestureRecognizerUILongPressGestureRecognizer
UIPanGestureRecognizer
UIPinchGestureRecognizer
UIRotationGestureRecognizer
UISwipeGestureRecognizer
UITapGestureRecognizer
UIImage
UILocalizedIndexedCollation
UIMenuController
UINavigationItem
UIPasteboard
UIPopoverController
UIScreen
UIScreenMode
UISearchDisplayController
UIResponderUIApplication
UIViewUIWindow
UILabel
UIPickerView
UIProgressView
UIActivityIndicatorView
UIImageView
UITabBar
UIToolbar
UINavigationBar
UITableViewCell
UIActionSheet
UIAlertView
UIScrollViewUITableView
UITextView
UISearchBar
UIWebView
UIControlUIButton
UIDatePicker
UIPageControl
UISegmentedControl
UITextField
UISlider
UISwitch
UIViewControllerUISplitViewController
UITabBarController
UITableViewController
UINavigationControllerUIImagePickerController
UIVideoEditorController
UITextRange
UITextInputStringTokenizer
UITextPosition
UITouch

(見易い図は『UIKit class hierarchy』をご覧下さい)


●UIKitとAppKit

AppKitは、Mac OS XでCocoaアプリケーションのユーザインターフェイスを担うフレームワークで、iPhone OSのCocoa touchアプリケーションにおけるUIKitに相当します。

iOSテクノロジーの概要』でその差異について述べられていますが、そこからUIKitの特徴をまとめてみます。

・インターフェイステクノロジー

(iPhone OS 4.0でマルチタスク対応になりましたが)iPhone OSにおいてウィンドウは1つだけです。

・ビュークラス

マウスとキーボードで操作するMacと違い、iPhone OSデバイスは指による操作に最適化されたビューとコントロールを提供しています。

・ビューの座標系

Mac OS Xが画面の左下角を原点としているのに対し、iPhone OSでは左上角を原点とした座標系になっています。

・ビューとしてのウィンドウ

Mac OS XではNSResponderのサブクラスとして、NSWindowとNSViewがあるのに対し、iPhone OSではUIResponderのサブクラスにUIView、そのサブクラスとしてUIWindowが実装されています。

Mac OS XiPhone OS
NSResponderNSWindow
 NSView
UIResponder - UIView - UIWindow

UIWindowがUIViewのサブクラスであることによって、iPhone OSのウィンドウはCore Animationを利用して描画したり、ウィンドウのレイヤ化を実現しています。

またウィンドウは1つしか作れないので、画面を切り替えたい場合はウィンドウではなく、ビューを切り替えることになります。

・イベント処理

イベント処理もマウスやキーボードによるMac OS Xと異なり、タッチイベントにより実行されます。

・ターゲット/アクションモデル

ユーザとアプリケーションの対話において、ユーザが画面をタップするなど操作をすると、コントロールがアクションメッセージとして、それに対応するオブジェクト(ターゲット)に送信します。

iPhoneでは、このコントロールが一対一だけではなく、一つの操作に対して複数のターゲットに各々異なるアクションを送信することが可能です。

・描画と印刷サポート

UIKitの描画機能は、Quartzの画像とカラーの操作向けにObjective-Cラッパーを提供しており、他にもOpen GL ESやCore Animationもサポートしています。

印刷は現在サポートしていませんが、iPhone OS 4.0でサポートされるという噂もあります。
(『ギズモード・ジャパン/iPhone OS 4.0には印刷機能がつく?』参照)

・テキストサポート

電子メールとメモ作成を対象としているため、多少複雑なHTMLコンテンツの表示や編集ができる程度です。

・アクセサメソッドとプロパティの使用

簡易アクセサメソッドであるプロパティが広範囲で利用可能です。

プロパティは2007年10月26日に発売されたMac OS X 10.5で、Objective-C 2.0から導入されたものですが、iPhone OSが開発者向けにSDKを公開したのが2008年6月のWWDCですので、積極的に利用されています。

・コントロールとセル

Mac OS Xでは処理の重いNSViewに対し、軽量な画面描画手段としてセル(NSCell)がありますが、iPhone OSのUIViewは処理が軽いため、NSCellに対応するクラスはありません。
(UITableViewCellはUITableViewオブジェクトに表示されるセル用のクラスです)

・Table View

iPhone OSのUITableViewクラスは、Mac OS XのNSTableViewクラスと異なり、画面に1列しか表示できないという制限がありますが、グループ化や階層表示などで補っています。

そういえば3.2でiPadに対応しているからもしやと思いましたが、追加されたのはbackgroundViewメソッドとTable Cell Insertion and Deletion AnimationにUITableViewRowAnimationMiddleだけで、その辺の拡張は無かったようです。
(ちなみに現在の4.0はiPad未対応なので変わっていませんでした)

・メニュー

デスクトップのアプリケーションより規模が小さいため、Mac OS XにおけるメニューバーはiPhone OSには無く、代わりにツールバーやボタンセットなどで対応します。

・Core Animationレイヤ

iPhone OSの場合、ビュー関連のプロパティで簡易なアニメーション処理が可能で、より複雑な処理が必要な場合にCore Animationを使います。



参考文献

UIKit Framework Reference

UIApplication Class Reference

UITableView Class Reference

iOSテクノロジーの概要

iOSアプリケーションプログラミングガイド

福井高専IT研究会OfficialWiki/UIControl

iPhone SDK 3 プログラミング大全 実践プログラミング (MacPeople Books)iPhone SDK 3 プログラミング大全 実践プログラミング (MacPeople Books)
(2009/09/08)
木下 誠

商品詳細を見る

サンドボックス

2010. 04. 13
●サンドボックスとは

サンドボックスはセキュリティ用語のひとつで、外部から受け取ったプログラムを隔離した領域内でのみ動作を許可する方式のことです。

iPhoneの場合、OS標準以外のアプリケーションは各ディレクトリ(サンドボックス)毎に隔離され、そのディレクトリ内であればファイルをダウンロードしたり、ファイルを作ったりできます。

しかし他のディレクトリへのアクセスは基本的に禁止されていて、極一部のデータのみフレームワークを介してアクセスを許可されています。
(アプリケーションの環境設定とデータも、サンドボックス内に入れられます)


●サンドボックスの構成

iPhone Simulatorの場合、デフォルトのインストール設定でver.3.1.3の場合は、

/Users/(ユーザ名)/Library/Application Support/iPhone Simulator/3.1.3/Applications/

のディレクトリ下に各アプリケーションのディレクトリ(サンドボックス)が作成されます。
(iPhone Simulatorに複数のバージョンがある場合は、各バージョンのディレクトリ毎にアプリケーションディレクトリが作成されます)

219

<Application_home>/AppName.app

アプリケーションのホームディレクトリ(バンドルのディレクトリ)が<Application_home>で、AppName.appがアプリケーションファイル(バンドル)です。
iPhone OS 2.1以降、AppStoreから購入したアプリケーションの最初の同期を除いて、iTunesによるバックアップは行われません。

<Application_home>/Documents/

アプリケーション固有のデータファイルを書き込む場所で、ユーザデータなどの保存に使います。
このディレクトリはiTunesによってバックアップされます。

<Application_home>/Library/Caches

アプリケーション終了後、次回起動時まで保持したいアプリケーション固有データの保存場所です。
このディレクトリのファイル管理は、基本的にアプリケーション側で対処する必要があります。
ただし、デバイスの完全復元時にこの場所のデータは破棄されます。
またiPhone OS 2.2以降、このディレクトリはiTunesによるバックアップは行われません。

<Application_home>/Library/Preferences

アプリケーション固有の環境設定ファイルを保存する場所です。
このディレクトリはiTunesによってバックアップされます。

<Application_home>/Tmp/

アプリケーション終了後、次回起動時まで保持したいアプリケーション固有データの保存場所です。
このディレクトリのファイル管理は、基本的にアプリケーション側で対処する必要がありますが、システムが古いファイルとして削除する場合もあります。
またiPhone OS 2.1以降、このディレクトリはiTunesによるバックアップは行われません。


●ディレクトリへのアクセス方法

iPhone Simulatorで、アプリケーションを入れたり消したりしていると気付くと思いますが、各アプリケーションフォルダ名はインストール時にその都度決められ、同じアプリケーションでも入れ直すと違う名前に成ります。

従ってアプリケーション内でファイルを作成したりアクセスするには、(これまでのサンプルコードのように)絶対パスで指定するのではなく、関数を使ってパスを取得する必要が有ります。

// Documentsディレクトリのパスを取得
NSArray *docPath;
NSString *outPath;

docPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

if ([docPath count] > 0) {
    outPath = [docPath objectAtIndex:0];
}
NSLog(outPath);

/*
iPhone Simulatorの場合
/Users/yayoi/Library/Application Support/iPhone Simulator/3.1.3/Applications/(略)/Documents
実機の場合
/var/mobile/Applications/(略)/Documents
*/

// Homeディレクトリのパスを取得
NSString *homePath = NSHomeDirectory();
NSLog(homePath);

// tmpディレクトリのパスを取得
NSString *tmpPath = NSTemporaryDirectory(); 
NSLog(tmpPath) 


・NSHomeDirectory

NSString * NSHomeDirectory (void);

現在のユーザのホームディレクトリのパスを返します


・NSSearchPathForDirectoriesInDomains

NSArray * NSSearchPathForDirectoriesInDomains (
    NSSearchPathDirectory directory,
    NSSearchPathDomainMask domainMask,
    BOOL expandTilde
);

ディレクトリ検索パスのリストを作成します

指定したドメイン内の指定したディレクトリから、パスの文字列によるリストを作成します

リストは検索された順序になります

expandTildeがYESの場合は、stringByExpandingTildeInPathを呼び出して、チルダを展開します

注:このメソッドは存在しないディレクトリを返すことがあります
このメソッドは単に指定されたディレクトリに合った場所を返します
開発者が必要に応じてアプリケーションが必要とするパスに修正しなければならない場合があります


・NSSearchPathDirectory

NSSearchPathDirectoryは、検索するパスのディレクトリを指定するもので、NSPathUtilities.hで定義されています

enum {
    NSApplicationDirectory = 1,
    NSDemoApplicationDirectory,
    NSDeveloperApplicationDirectory,
    NSAdminApplicationDirectory,
    NSLibraryDirectory,
    NSDeveloperDirectory,
    NSUserDirectory,
    NSDocumentationDirectory,
    NSDocumentDirectory,
    NSCoreServiceDirectory,
    NSAutosavedInformationDirectory = 11,
    NSDesktopDirectory = 12,
    NSCachesDirectory = 13,
    NSApplicationSupportDirectory = 14,
    NSDownloadsDirectory = 15,
    NSInputMethodsDirectory = 16,
    NSMoviesDirectory = 17,
    NSMusicDirectory = 18,
    NSPicturesDirectory = 19,
    NSPrinterDescriptionDirectory = 20,
    NSSharedPublicDirectory = 21,
    NSPreferencePanesDirectory = 22,
    NSItemReplacementDirectory = 99,
    NSAllApplicationsDirectory = 100,
    NSAllLibrariesDirectory = 101
};
typedef NSUInteger NSSearchPathDirectory;

NSApplicationDirectory1サポートされるアプリケーション(/Applications)
NSDemoApplicationDirectory サポートされないアプリケーションとデモバージョン
NSDeveloperApplicationDirectory デベロッパアプリケーション(/Developer/Applications)
NSAdminApplicationDirectory システムとネットワーク管理アプリケーション
NSLibraryDirectory 色々なドキュメンテーション、サポート、コンフィグファイル
(/Library)
NSDeveloperDirectory デベロッパリソース(/Developer)
NSUserDirectory ユーザのホームディレクトリ(/Users)
NSDocumentationDirectory ドキュメンテーション
NSDocumentDirectory ドキュメントディレクトリ
NSCoreServiceDirectory Core Servicesの位置(System/Library/CoreServices)
NSAutosavedInformationDirectory11ユーザがドキュメントをオートセーブする位置
(Library/Autosave Information)
NSDesktopDirectory12ユーザのデスクトップディレクトリの位置
NSCachesDirectory13破棄キャッシュファイルの位置(Library/Caches)
NSApplicationSupportDirectory14アプリケーションのサポートファイルの位置
(Library/Application Support)
NSDownloadsDirectory15ユーザのダウンロードディレクトリの位置
NSUserDomainMaskが提供されている場合のみフラグが立て
られます
NSInputMethodsDirectory16入力メソッドの位置(Library/Input Methods)
NSMoviesDirectory17ユーザのムービーディレクトリの位置(~/Movies)
NSMusicDirectory18ユーザのミュージックディレクトリの位置(~/Music) 
NSPicturesDirectory19ユーザの画像ディレクトリの位置(~/Pictures)
NSPrinterDescriptionDirectory20システムのPPDディレクトリの位置(Library/Printers/PPDs)
NSSharedPublicDirectory21ユーザの共有ディレクトリの位置(~/Public)
NSPreferencePanesDirectory22システム環境設定の環境設定パネルの位置
(Library/PreferencePanes)
NSItemReplacementDirectory99NSFileManagerメソッドで使用
NSAllApplicationsDirectory100アプリケーション以下の全ディレクトリ
NSAllLibrariesDirectory101リソース以下の全ディレクトリ

大きな声では言えませんが、イタリックで示した8つの検索パスディレクトリ

NSAutosavedInformationDirectory
NSInputMethodsDirectory
NSMoviesDirectory
NSMusicDirectory
NSPicturesDirectory
NSPrinterDescriptionDirectory
NSSharedPublicDirectory
NSPreferencePanesDirectory

は、iPhone OS 3.2以下では使用できません(後はお察しください)

※ PPD(PostScript Printer Description)はPostScriptプリンタ用に機能を指示するファイルのことです


・NSSearchPathDomainMask

NSSearchPathDomainMaskは、検索するパスの範囲を指定するもので、NSPathUtilities.hで定義されています

enum {
    NSUserDomainMask = 1,
    NSLocalDomainMask = 2,
    NSNetworkDomainMask = 4,
    NSSystemDomainMask = 8,
    NSAllDomainsMask = 0x0ffff,
};
typedef NSUInteger NSSearchPathDomainMask;

NSUserDomainMask1ユーザのホームディレクトリ(個人アイテムをインストールしてい
る場所)(~) 
NSLocalDomainMask2現在のマシンの利用者全員分のアイテムがインストールされている
場所
NSNetworkDomainMask4LAN内で共有している(ネットワーク上でアイテムがインストール
されている)場所(/Network) 
NSSystemDomainMask8Appleが提供。変更不可(/System) 
NSAllDomainsMask0x0ffff全て(将来加わるもの全てを含む)


・NSTemporaryDirectory

NSString * NSTemporaryDirectory (void);

現在のユーザのテンポラリ(一時)ディレクトリのパスを返します

ディレクトリが無い場合はnilを返します



参考文献

Foundation Functions Reference

Foundation Data Types Reference

iOSアプリケーションプログラミングガイド

IT用語辞典/サンドボックス

Wikipedia/サンドボックス

Wikipedia/PostScript Printer Description

iPhone SDK 3 プログラミング大全 実践プログラミング (MacPeople Books)iPhone SDK 3 プログラミング大全 実践プログラミング (MacPeople Books)
(2009/09/08)
木下 誠

商品詳細を見る

Foundation(タイマー)

2010. 04. 13
解説中に出てくるデフォルトモードについて紹介します。

Cocoa Break!/Dev/ソース/Examples/App Kit/Worm』によると、『デフォルトモード(NSDefaultRunLoopMode)』との記述があります。

NSRunLoop Class Reference』でNSDefaultRunLoopModeを調べると、実行ループモードの一つと分かりました。

●実行ループモード(Run Loop Modes)

NSRunLoop.hで定義されているものが2つ有ります。

・NSDefaultRunLoopMode
・NSRunLoopCommonModes

他にもNSConnectionとNSApplicationで定義されているものが3つ有ります。

・NSConnectionReplyMode
・NSModalPanelRunLoopMode
・NSEventTrackingRunLoopMode

ただ、『NSDefaultRunLoopMode』の解説も、

NSConnectionオブジェクト以外の入力ソースを扱います
最もよく利用されている実行ループモードです

としか書いてない困ったものでして、これ以上の追求は止めました。

おそらく、アプリケーションを起動すると自動的に作られる実行ループで、イベントループやタイマーもこの上に作られる(実行ループ内で管理される)ものと思われます。


●タイマーのクラス図

Foundation
NSTimer

- (void)startTimer
{
    // タイマーを作成してスタート
    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(timerFired:) userInfo:nil repeats:YES];
}

- (void)timerFired:(NSTimer *)timer
{
    // タイマー発動時に呼び出されるメソッド
}


・scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:

+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)seconds target:(id)target selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)repeats

デフォルトモードの現在の実行ループの中に新規にNSTimerオブジェクトを作成し、返します

seconds:タイマーの発動間隔を秒単位で指定します
0.0秒以下を指定した場合は0.1ミリ秒に補正されます

target:タイマーの発動時にaSelectorのメッセージを送るオブジェクトを指定します
このオブジェクトは、タイマーが解放されるまで保持されます

aSelector:タイマーの発動時にtargetに送るメッセージを指定します
セレクタは次のような記述に成ります

- (void)timerFireMethod:(NSTimer *)theTimer

このメソッドの引数としてタイマーは自分自身を渡します

userInfoタイマーにユーザが情報を渡したい場合に指定します
※2010.5.23訂正
タイマーがaSelectorのメソッドに渡すユーザ情報を指定します
このオブジェクトは、タイマーが解放されるまで保持されます
このパラメータはnilを指定できます

repeats:YESの場合は無効にするまでタイマー動作を繰り返します
NOの場合は一度だけタイマー動作を発動します



参考文献

NSTimer Class Reference

NSRunLoop Class Reference

Mosaic Browsing/11/2009 - 12/2009

Cocoa Break!/Dev/ソース/Examples/App Kit/Worm

仙台単身赴任生活/Mac用USBデバイス-31 ホスト側のサンプルコード

iPhone SDK 3 プログラミング大全 実践プログラミング (MacPeople Books)iPhone SDK 3 プログラミング大全 実践プログラミング (MacPeople Books)
(2009/09/08)
木下 誠

商品詳細を見る

詳解 Objective-C 2.0 第3版詳解 Objective-C 2.0 第3版
(2011/12/28)
荻原 剛志

商品詳細を見る






Bose QuietComfort 20
Calendar
03 | 2010/04 | 05
Sun Mon Tue Wed Thu Fri Sat
- - - - 1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 -
Recent Articles
iTunes


Swift
Categories
Tips
Profile

水月杏香

Author:水月杏香
永遠の初心者プログラマ。

Wish List
WACOM


ARC
Technical Q&A
情報プロパティリストキー
Start Developing iOS Apps Today
BOSE

Bose QuietComfort 20
Reference
NSApplicationDelegateプロトコル
NSArrayクラス
NSAutoreleasePoolクラス
NSBundleクラス
NSBundle UIKit追加分
NSCalendarクラス
NSCoderクラス
NSCodingプロトコル
NSCopyingプロトコル
NSDataクラス
NSDateクラス
NSDateFormatterクラス
NSDictionaryクラス
NSEntityDescriptionクラス
NSEnumeratorクラス
NSErrorクラス
NSExceptionクラス
NSFetchRequestクラス
NSFileHandleクラス
NSFileManagerクラス
NSIndexPathクラス
NSIndexPath UIKit追加分
NSKeyedArchiverクラス
NSKeyedUnarchiverクラス
NSKeyValueCodingプロトコル
NSLocaleクラス
NSManagedObjectクラス
NSManagedObjectContextクラス
NSManagedObjectModelクラス
NSMutableArrayクラス
NSMutableCopyingプロトコル
NSMutableDictionaryクラス
NSMutableSetクラス
NSNotificationクラス
NSNotificationCenterクラス
NSNullクラス
NSNumberクラス
NSObjectクラス
NSObject UIKit追加分
NSObjectプロトコル
NSPersistentStoreクラス
NSPersistentStoreCoordinatorクラス
NSPredicateクラス
NSPropertyListSerializationクラス
NSRunLoopクラス
NSSetクラス
NSStringクラス
NSString UIKit追加分
NSTimerクラス
NSTimeZoneクラス
NSURLクラス
NSURLProtectionSpaceクラス
NSURLRequestクラス
NSUserDefaultsクラス
NSValueクラス

UIActionSheetクラス
UIActionSheetDelegateプロトコル
UIActivityIndicatorViewクラス
UIAlertViewクラス
UIAlertViewDelegateプロトコル
UIApplicationクラス
UIApplicationDelegateプロトコル
UIBarButtonItemクラス
UIBarItemクラス
UIButtonクラス
UIColorクラス
UIControlクラス
UIDatePickerクラス
UIDeviceクラス
UIEventクラス
UIFontクラス
UIGestureRecognizerクラス
UIImageクラス
UIImageViewクラス
UIKit Function
UILabelクラス
UINavigationControllerクラス
UINavigationItemクラス
UIPickerViewクラス
UIPickerViewDataSourceプロトコル
UIPickerViewDelegateプロトコル
UIPinchGestureRecognizerクラス
UIResponderクラス
UIScreenクラス
UIScrollViewクラス
UISearchBarクラス
UISearchBarDelegateプロトコル
UISegmentedControlクラス
UISliderクラス
UISwipeGestureRecognizerクラス
UISwitchクラス
UITableViewクラス
UITableViewCellクラス
UITableViewControllerクラス
UITableViewDataSourceプロトコル
UITableViewDelegateプロトコル
UITapGestureRecognizerクラス
UITextFieldクラス
UITextFieldDelegateプロトコル
UITextInputTraitsプロトコル
UITextViewクラス
UITextViewDelegateプロトコル
UIToolbarクラス
UITouchクラス
UIViewクラス
UIViewControllerクラス
UIWebViewクラス
UIWebViewDelegateプロトコル
UIWindowクラス

AVAudioPlayerクラス
AVAudioPlayerDelegateプロトコル

CADisplayLinkクラス
CAEAGLLayerクラス
CALayerクラス

CGAffineTransform
CGBitmapContext
CGColor
CGColorSpace
CGContext
CGGeometry
CGImage
CGPath

EAGLContextクラス
EAGLDrawableプロトコル

Foundation Constants
Foundation Data Types
Foundation Functions

MPMediaItemクラス
MPMediaItemArtworkクラス
MPMediaPlaylistクラス
MPMediaPropertyPredicateクラス
MPMediaQueryクラス
MPMusicPlayerControllerクラス

Randomization Services

System Sound Services
Amazon


OpenGL ES
SQLite
Monthly Archives
Recent Comments
Recent TrackBacks
RSS Link
Visitors
QR Code
QR