フナミタカオです。
初の日本語で読めるiPhoneSDK解説本「自作アプリをApp Storeで世界に向けて販売できる!! iPhone SDKプログラミング大全 (MacPeople Books)僕も、昨年くれから、アマゾンで予約していたのですが、発売日になっても、発送されず、いきなり在庫切れ。(1月8日時点ではアマゾン内で19位になってました。)相当な人気のようです。銀座界隈の本屋さんでも売り切れとのことで、自宅近所の横浜の有隣堂でやっとみつけました。アップルから提供されている公式の日本語ドキュメントも公開されていましたが、コンパクトにまとめられた、書籍は、やっぱり、助かります。さっそく、読み始めていますが、iPhone開発を初めて開発する場合、障壁(要勉強)となる、「Objective-C」、「Foundation」、「UI Kit」、「Cocoa Touch」等について、「かゆいところ」をきちんと説明してくれています。
僕も公式の日本語ドキュメントが読み切れず、しばらく、放置してしまっていたのですが、この機会に本腰入れようとおもいます。
2008年のSDK発表以来、iPhoneSDKがアップデートされるたびに、インストールしてきたのですが、なかなかObjective-Cになれることができず、サンプルを動かすことはできても、自分のコードがかけてないという方も多いのではないでしょうか?
僕も実は、そうです。
アップルの日本語ドキュメントもうれしかったのですが、量が多すぎてちょっと、ぼーっとしているうちに、ほかの仕事が舞い込んでなかなか、すすまずにおりました。
そんな方には、このほんおすすめです。
300ページという手頃な量で、詳しすぎない内容です。
初めてのiPhone開発でつまづいそうな所を、押さえて、解説してくれているので、まずは、この本の内容を理解すれば、サンプルコードを自信をもって、改造できるようになるかと思います。
詳細なドキュメントは、iPhone Dev Centerに山ほどあるので、そのドキュメントを読む前の下準備として、この本で、基礎をかためましょう。
僕自身、Ruby、Perl、Javascriptで普段開発していて、オブジェクト指向の開発をやっています。
Macに関しては、5年くらいまえまでAppleScriptを使った巨大なアプリを作ったことがありますが、Objective-Cはこれが初めて。Cの開発はほとんど無し。クライアントアプリはVB.NETでの開発経験があります。こういうスキルセットの方には、ちょうど良さげな内容です。
たぶん、既にXcodeを使いこなせている方や、Macの開発経験があるかたには、物足りない内容かもしれません。「自作アプリをApp Storeで世界に向けて販売できる」といいつつ、実際のAppStoreへの登録方法は詳しくは説明されていません。実機でテストするためにプロビジョニングファイルの設定とかが必要になるんですが、その辺もないです。
ま、すべて網羅するのは、無理な話ですので、この本はiPhone Dev Centerに入る前のガイドブックとして使うには最適です。
この本ですっきりした7つのポイント
1.Objective-Cの呪文が読めるようになる- iPhoneSDK大全-61P〜
たぶん、iPhone開発を初めて、ぶつかる障壁のNo1がこの言語。オブジェクト指向がわかっていても、[hoge fuga]のように、鍵括弧で囲まれた呪文に悩ませられます。これが実は、メソッド呼び出し。
NSString* string; string = @"Hello World"; //これで、NSString型のオブジェクト(インスタンス)ができてstringにそのポインタが格納される。 int len; len = [string length]; //ここが重要。string のオブジェクトのlengthメソッドを呼んでいることになる[オブジェクト メソッド]
引数がある場合
[string characterAtIndex:0]これで、0がcharacterAtIndexメソッドの引数になる。 ま、ここまでは、わかるのだが、ややこしいのは、引数が2つ出てきた場合。
NRRange = range; range = [string rangeOfString:@"Hello" options:NSCaseIntensiveSearch]2つの引数があるときは、引数名のあとに数値をつける、ただし、第一引数は引数名が無い。 ここが、はまりどころ。第一引数名なのか、メソッド名なのか、混乱してしまうのだけど、第二引数以降には、引数名があるということがわかればすっきりできる。しかも、メソッド名は引数名をふくめるとのこと。
つまり この場合のメソッド名は
rangeOfString:options: となる。:(セミコロン)も含むというのも、なれないと、わかりにくい点。
このメソッドの規約以外にも、クラスの書き方や、プロトコル、プロパティの説明がされています。
プロパティ自体実はObjective-C2.0からできたもので、つい最近のことのようです。
さて、本の中では、C++との比較をされていますが、ここまでをRubyと比べてみます
68P〜83Pあたりに、登場する、Peronクラスで比較。
Objective-C
.hと.mの二つのファイルを用意して、hにはインターフェースを、.mに実装を書くperson.h
@interface Person : NSObject {
int age;
NSString* firstName;
NSString* lastName;
}
@property int age;
@property (retain) NSString* firstName;
@property (retain) NSString* lastName;
@property (readonly) NSString* fullName;
- (BOOL)isAdult;
@end
person.m
#import "person.h"
@implementation Person
@synthesize age;
@synthesize firstName;
@synthesize lastName;
- (NSString*)fullName
{
return [NSString stringWithFormat:@"%@ %@",firstName, lastName];
}
- (BOOL)isAdult
{
return age > 19;
}
// 2008.1.14 deallocメソッド追加。プロパティのリリースも必要らしいので
- (void)dealloc {
[firstName release];
[lastName release];
[super dealloc];
}
@end
追記:2008/1/14retainをつけた、プロパティのリリースが必要かどうか、気になっていたのですが、やっぱり、必要そうです。 [iPhone SDK] @property (nonatomic, retain) の挙動
@property (nonatomic, retain)は,新しく外部からオブジェクトをセットすると,古いオブジェクトには,releaseが渡される. ただし,dealloc時に自動的にreleaseは投げられないので,dealloc時には,プロパティにreleaseを自前で投げる必要がある.追記ここまで
Ruby
Rubyだと1ファイルになる、プロパティはattr_accessorで実装してみたperson.rb
class Person
def initialize
@age = 0
@first_name = ''
@last_name = ''
end
def full_name
return "%s %s" % [@first_name,@last_name]
end
def is_adult
return @age > 19
end
attr_accessor :age,:first_name,:last_name
end
そして、このクラスの使い方は
Objective-C
#import <Foundation/Foundation.h>
#import "person.h"
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
// ここからお試し
Person* person;
person = [[Person alloc] init];
person.age = 50;
person.firstName = @"Steave";
person.lastName = @"Jobs";
NSString* fullName ;
fullName = person.fullName;
NSLog(fullName);
[person release];
//ここまで
[pool drain];
return 0;
}
Ruby
person = Person.new person.age = 50 person.first_name = "Steave" person.last_name = "Jobs" full_name = person.full_name is_adult = person. is_adult p full_name p person.is_adultとなる。あたりまえですが、Objective-Cはmainが必要だし、コンパイルも必要です。このあたり、「iPhoneSDK大全」では、一部のサンプルコードのみなので、そのままでは、動きません。このあたり、初心者としてあは、とまどいました。Xcodeを使っているのであれば、新規プロジェクト>Command Line Utility>Foundation Toolを使って、ちょっと強引ですが、mainブロックに書いちゃえば、試すことができます。
2.Objective-Cはメモリ管理を自分でやらないといけない- iPhoneSDK大全86P〜
Ruby等のスクリプトでは、メモリ解放をしなくても、いい感じでガベージコレクトされます。Objective-Cも2.0からガベージコレクションが搭載されたのですが、iPhoneでは、利用できないとのこと。参照カウンタを使った、手動による、メモリ管理が必要。不必要になったら、releaseメソッドを呼ばないとけません。
なので、前述のコードも
Objective-C
Person* person; person = [[Person alloc] init]; person.age = 50; person.firstName = @"Steave"; person.lastName = @"Jobs"; NSString* fullName ; fullName = person.fullName; person.release; //ここで、明示的に解放することが必要。実は、解放のタイミングを、不要になったら、解放してくれるautolereaseという機能がもある。
例えば、person = [[[Person alloc] init] autorelease];
とすれば、よいらしい。
Person* person; person = [[[Person alloc] init] autorelease]; person.age = 50; person.firstName = @"Steave"; person.lastName = @"Jobs"; NSString* fullName ; fullName = person.fullName; //person.release; //不要になるNSStringは [NSString stringWithFormat:@"%@ %@",firstName, lastName]; のようにstringHogeHogeのメソッドはautolereaseされるNSStringクラスのインスタンスを生成する。
先述のソースであれば、fullNameという変数には、NSStringクラスのインスタンスがセットされるが、それは、return [NSString stringWithFormat:@"%@ %@",firstName, lastName];で生成されたインスタンスなので、autolereaseされていると見なしてもよいのかとおもうが、いったいいつ消えるのか?不要になったらとは、いつか?それが自動的に判断できるならガベージコレクションとなにが違うのか?とここで疑問がわいてきた。「iPhoneSDK大全」89Pには
(前略)〜retainする必要がなく、しかも使い終わったあとに自動でreleaseされる、という仕組みが用意されている。これを自動解放と呼ぶ。(後略)と書かれているのだが、使い終わったあととはいつなのか?やっぱりわからない。
いくつか調べてみると、すごいことがわかった
Cocoaのメモリ管理(3)
デフォルトのNSAutoreleasePoolは、プログラムの最後に(つまり、メインスレッドの末端で)解放されるので、基本的にこれに登録されたオブジェクトに割り当てられたメモリはプログラムの最後まで解放されない。つまり、自動的というよりは、解放せずにためといて、最後に捨てましょうということである。
そういえば、iPhoneアプリのmainブロックでは、最初にNSAutoreleasePoolの初期化をしている。
#importつまり、デフォルトでは、autoreleaseされたインスタンスは、このプールにどんどん、追加されてゆく。ちょっとした文字列であっても NSString.stringWithFormatを乱発すると、メモリ不足になりかねないということです。注意、注意。int main(int argc, char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; int retVal = UIApplicationMain(argc, argv, nil, nil); [pool release]; return retVal; }
追記2008/1/14
iPhoneアプリ開発者の岸川克己さんのブログ「autoreleaseされたオブジェクトはいつ解放されるか - 24/7 twenty-four seve」からトラックバックをいただきました。どうもありがとうございます。
NSAutoreleasePoolはイベントループが一周するたびに生成と破棄を繰り返します。 ですので、アプリケーション終了まで、オブジェクトが溜まっていくということはありません。 たいていは、autorelease済みのオブジェクトはメソッドを抜けた後に解放されます。イベントループごとに解放されるということで、アプリ起動中に、すべてのインスタンスが、解放されずに蓄積することはないということですね。
ただし、一つのメソッド内で、大量のメモリを使う場合は、ループ中に自分でNSAutoreleasePoolを作ったほうがよいこともあるそうです。
参照:一時オブジェクトを大量に使う(メモリを消費する)処理をループする場合は、ループの中で自動解放プールを生成する - 24/7 twenty-four seven 岸川さんどうもありがとうございました。
追記-ここまで
3.Core FundationとFundationの違いがなにかがわかる- iPhoneSDK大全-94P〜
「iPhoneSDK大全」まで、こんな区別があるとは知りませんでした。 FundationはObjective-CベースでCoreFundationはC言語ベースという違いだそうです。Carbonフレームワークとの互換性ということですが、CoreFundationはCなので、メソッドではなくて関数呼び出しになります。
お互いの変換は、コスト0だそうです。一緒に使うライブラリとの相性でどちらを呼ぶかえらべるということですね。
4.サンドボックスの思想がわかる- iPhoneSDK大全-125P〜
iPhoneのセキュリテリィ思想ですが、各アプリケーションはサンドボックスという区画で区別され、お互いのファイルを共有することはできない。アドレスブックのようにデータのやり取りをできるアプリもあるが、これもフレームワーク経由となる。自分で2つのアプリを作って、お互いのデータを共有することはできないということだが、無理やるとしたら、http経由で外部のストレージを呼ぶということか。DropBoxのようなものがあればいのかもしれない。いづれにしても、通信にともなう、タイムラグはたっぷりありそう。オフラインでもつかえないなあ...
5.xibファイルによって、ユーザーインターフェースとソースを分離できるというのはどういうことか- iPhoneSDK大全-52P〜
xibに入っているのは、インスタンスそのものをシリアライズしたもの。インターフェースビルダーで配置した部品はインスタンスとしてxibに保存される。よって、配置や、サイズもインスタンスとして覚えているので、読み込むと、UIのインスタンス群ができていることになる。 この辺の詳細は「チュートリアルの中で随時説明してゆく」と述べられているが、そのチュートリアルがどれなのか、わかりにくいが140P〜185PのUIKitを使ったアプリケーションの章が、そのチュートリアルのようで、結構量があるので、これからじっくり取り込もうと思っています。 とりあえず、xlibには、コードは無くて、本当にUIのインスタンスなんだなあということがわかりました。6.Core LocationでGPSが使えるようになる- iPhoneSDK大全-215P〜
位置、高度、精度、スピード、向きを取得することができる。Google Mapは、最初、おおまかな精度でマップが表示されて、その後、詳細な位置がポイントされるが、この精度を見ながら、一定の時間を置いて計測を繰り返しているということになるのでしょうか。向きとスピードまでとれるのはおもしろい。
7.UIViewまたは、Core Animationでかっこいい遷移ができる- iPhoneSDK大全-269P〜
トランジションはInterfaceBuilderで、プルダウンで選択できるのではと思っていましたが、そんなことはなくて、地道なコーディングでした。まだもやもやしていること
テストはどうやるのだろう?
テスト駆動型で開発することが多いのですが、この本だけでは、ユニットテストのことは解説されていません。Xcode Unit Testing GuideというドキュメントにはXcodeプロジェクトにて新規ターゲットtしてCocoa>Unit Test Bundleを追加しなさいとなっていますが、iPhoneのプロジェクトで試したら、エラーがたくさん出ました。まだ、さっと読んだだけで、チュートリアルも途中です。全部読んだらきっと、もっとすっきりすると思いますが、もやもやも出てくるのでしょう。
熟読してみます。
ところで、いつ買えるのかしら
僕は、1月8日にアマゾンからの発送をあきらめで、本屋さんで探したのですが、1月13日現在アマゾン自作アプリをApp Storeで世界に向けて販売できる!! iPhone SDKプログラミング大全 (MacPeople Books)どのショップも同じような条件のようなので、予約して気長にまつのかな。
まてば、まつだけ、届いたときに、うれしいかもしれません。このおきおいでiPhone開発者が増えることを期待しています。
1/13 21:10 追記 livedoor boosでは発送可能時期:24時間になっています 1/13 23:07 追記 livedoor boosでも、品切れになりました!
関連エントリ
・iPhone SDK日本語ドキュメント遂に登場!・iPhoneシミュレーターを試す。Safariがサクサク、日本語入力も可
・著者:木下誠さんのiPhone SDKプログラミング大全公式ページ、プレゼント企画もあり







コメント (4)
>デフォルトでは、autoreleaseされたインスタンスは、このプールにどんどん、追加されてゆく。
>ちょっとした文字列であっても NSString.stringWithFormatを乱発すると、メモリ不足になりかねないということです。注意、注意。
NSAutoreleasePoolはイベントループが一周するごとに、生成と破棄を繰り返すので、アプリケーションの終了までメモリが解放されないわけではありません。
なのでautorelease済みのオブジェクトは、たいていはメソッドを抜けた時点で解放されます。
投稿者: 岸川克己 | 2009年01月14日 03:08
日時: 2009年01月14日 03:08
岸川さん、コメントありがとうございます。今後ともどうぞよろしくおねがいします。
初心者にとっては、メモリ管理は、結構、ハードルになりそうですね。
@property(retain)のプロパティはdeallocメソッド内で、明示的にreleaseしないといけないということも書き加えました。
投稿者: フナミタカオ | 2009年01月14日 15:53
日時: 2009年01月14日 15:53
HMDTのブログから飛んできました。
とても分かりやすい記事ですね。すごく参考になりました。
私もまだ買っていないのですが、どういう姿勢でこの本に臨めばよいかがこの記事で分かったので、効率よく読めそうです(多分)。
ありがとうございます、とお礼を言いたくてコメントしました。
失礼します。
投稿者: かときち | 2009年01月14日 19:47
日時: 2009年01月14日 19:47
かときちさん、コメントありがとうございます。
励みになります!現在、HelloWordのチュートリアルを読んで試してみて、デリゲートと.xibをつなぐための、IBOutlet,IBActionあたりの役割がちょっとわかったかもというところです。これだけ読むと、なんのことやらわかりませんが、132P〜149Pを読めば理解できると思います。
まだ、アマゾンは出荷待ちのようですね。
投稿者: フナミタカオ | 2009年01月15日 10:03
日時: 2009年01月15日 10:03