iphone, ipad アプリ開発勉強会#2

44
iPhone, iPad アプリ開発勉強会#2 12127日金曜日

Upload: hiroe-orz

Post on 28-Jun-2015

1.478 views

Category:

Technology


6 download

DESCRIPTION

iPhone, iPad アプリ開発勉強会#2 の為に作成した資料です。

TRANSCRIPT

Page 1: iPhone, iPad アプリ開発勉強会#2

iPhone, iPadアプリ開発勉強会#2

12年12月7日金曜日

Page 2: iPhone, iPad アプリ開発勉強会#2

一般的なアプリの構成

実行

@interface MyViewController {@private NSString *str}

@prototyp(non...

@end

@imprementation MyViewController {@synthesize *mView

- (id) init { self = [super init]; return self:}

@end

ヘッダファイル(MyViewController.h)

実装ファイル(MyViewController.m)

ビュー(MyViewController.xib)

画面ひとつ分の構成

通常は画面1つにつき、

•ビュー•ヘッダファイル•実装ファイル

で構成されます

12年12月7日金曜日

Page 3: iPhone, iPad アプリ開発勉強会#2

一般的なアプリの構成ビューが1つのとき

実行

@interface MyViewController {@private NSString *str}

@prototyp(non...

@end

@imprementation MyViewController {@synthesize *mView

- (id) init { self = [super init]; return self:}

@end

ヘッダファイル(MyViewController.h)

実装ファイル(MyViewController.m)

ビュー(MyViewController.xib)

@interface MyViewController {@private NSString *str}

@prototyp(non...

@end

@imprementation MyViewController {@synthesize *mView

- (id) init { self = [super init]; return self:}

@end

ヘッダファイル(MyAppViewDelegate.h)

実装ファイル(MyAppDelegate.m)

アプリケーションデリゲート

それ以外では、アプリひとつにつき、アプリケーションデリゲートが1つあります。

12年12月7日金曜日

Page 4: iPhone, iPad アプリ開発勉強会#2

一般的なアプリの構成ビューが2つのとき

@interface MyView

@imprementation MyView

ヘッダファイル 実装ファイル

ビュー

@interface MyViewController {@private NSString *str}

@prototyp(non...

@end

@imprementation MyViewController {@synthesize *mView

- (id) init { self = [super init]; return self:}

@end

ヘッダファイル(MyAppViewDelegate.h)

実装ファイル(MyAppDelegate.m)

アプリケーションデリゲート

@interface MyView

@imprementation MyView

ヘッダファイル 実装ファイル

ビュー

アプリケーションデリゲートはアプリ全体で共有します

12年12月7日金曜日

Page 5: iPhone, iPad アプリ開発勉強会#2

一般的なアプリの構成

@interface MyView

@imprementation MyView

ヘッダファイル 実装ファイル

ビュー

@interface MyViewController {@private NSString *str}

@prototyp(non...

@end

@imprementation MyViewController {@synthesize *mView

- (id) init { self = [super init]; return self:}

@end

ヘッダファイル(MyAppViewDelegate.h)

実装ファイル(MyAppDelegate.m)

アプリケーションデリゲート

@interface MyView

@imprementation MyView

ヘッダファイル 実装ファイル

ビュー

ヘッダファイル 実装ファイル

@interface MyView

@imprementation MyView

なんらかの機能を提供するクラス

12年12月7日金曜日

Page 6: iPhone, iPad アプリ開発勉強会#2

一般的なアプリ開発の流れ

1. XCodeでプロジェクト作成

2. ビューに部品(ボタン、テキストフィールド等...)を追加

3. ビューコントローラのヘッダファイルに@property(IBoutlet)宣言を追加

4. 実装ファイルに@synthesize宣言を追加

5. ビューのデザイン画面で、さきほど宣言したビューコントローラのプロパティと実際の部品を繋ぐ。

6. コード中でビューの部品にアクセスする際には@property宣言した変数を通して。

7. ボタンなどを配置してタップした時のアクションを定義する(次ページ)

12年12月7日金曜日

Page 7: iPhone, iPad アプリ開発勉強会#2

一般的なアプリ開発の流れ(アクションの定義)

1. デザイン画面にアクションを起こすボタンなどを配置する。

2. ビューコントローラのヘッダファイルにアクションのメソッド定義をする。

3. ビューコントローラの実装ファイルにアクションを実装する。

4. デザイン画面で、アクションと実際の部品を繋ぐ。

5. ボタンなどを配置して、そのボタンをタップした時のアクションのコードを書く。

6. コンパイル、動作を確認。

12年12月7日金曜日

Page 8: iPhone, iPad アプリ開発勉強会#2

メモリ管理

Rubyと同様に、Objective-Cにおいてもクラスからインスタンスを作って使用します。

obj = Hoge.new

obj.sayhello #メソッド呼び出し

Hoge *obj = [[Hoge alloc] init];

[obj sayhello] /* メソッド呼び出し */

[obj release]; /* メモリを解放 */

/* または */

[obj autorelease]; /* これもメモリ解放 */

Rubyの場合 Objective-Cの場合

12年12月7日金曜日

Page 9: iPhone, iPad アプリ開発勉強会#2

もしメモリを解放しないと...

90%

10%アプリが使用中空きメモリ

70%

30%

40%60%

40%60%

5%

95%

iPhoneの持ってるメモリを使い果たしてしまう!実際にはそうなる前にiOS

によりアプリが強制終了されます。

だんだんメモリ使用量が増えていって...

12年12月7日金曜日

Page 10: iPhone, iPad アプリ開発勉強会#2

メモリ解放するには、プログラム中で生成したオブジェクトを解放します。

オブジェクトは、誰にも使用されなくなったら解放します。

Hogeクラスのオブジェクト[[Hoge alloc] init]

オブジェクトA

オブジェクトB

オブジェクトC

オブジェクトが使われている(参照されている)状態

12年12月7日金曜日

Page 11: iPhone, iPad アプリ開発勉強会#2

メモリ解放するには、プログラム中で生成したオブジェクトを解放します。

オブジェクトは、誰にも使用されなくなったら解放します。

Hogeクラスのオブジェクト

オブジェクトA

オブジェクトB

オブジェクトC

オブジェクトが使われていない(参照されていない)状態こうなったら解放しちゃってもいい

12年12月7日金曜日

Page 12: iPhone, iPad アプリ開発勉強会#2

でも、他のオブジェクトから使われているかどうかなんて、どうやったらわかるのでしょう...

12年12月7日金曜日

Page 13: iPhone, iPad アプリ開発勉強会#2

Hogeクラスのオブジェクト

オブジェクトA

オブジェクトB

オブジェクトC

オブジェクトが使われている(参照されている)状態

3

Objective-Cでのメモリ管理にはリファレンスカウンタを使用します

リファレンスカウンタ

12年12月7日金曜日

Page 14: iPhone, iPad アプリ開発勉強会#2

Hogeクラスのオブジェクト

オブジェクトA

オブジェクトB

オブジェクトC

オブジェクトが使われている(参照されている)状態

2

Objective-Cでのメモリ管理にはリファレンスカウンタを使用します

リファレンスカウンタ

12年12月7日金曜日

Page 15: iPhone, iPad アプリ開発勉強会#2

Hogeクラスのオブジェクト

オブジェクトA

オブジェクトB

オブジェクトC

オブジェクトが使われている(参照されている)状態

1

Objective-Cでのメモリ管理にはリファレンスカウンタを使用します

リファレンスカウンタ

12年12月7日金曜日

Page 16: iPhone, iPad アプリ開発勉強会#2

Hogeクラスのオブジェクト

オブジェクトA

オブジェクトB

オブジェクトC

誰からも使われなくなったオブジェクトはリファレンスカウンタが0に!

0

Objective-Cでのメモリ管理にはリファレンスカウンタを使用します

リファレンスカウンタ

12年12月7日金曜日

Page 17: iPhone, iPad アプリ開発勉強会#2

Hogeクラスのオブジェクト

オブジェクトA

オブジェクトB

オブジェクトC

オブジェクトは解放されてなくなりました!リファレンスカウンタが0になったときの

オブジェクトの解放はiOSにより自動的に行われます。

0

Objective-Cでのメモリ管理にはリファレンスカウンタを使用します

リファレンスカウンタ

12年12月7日金曜日

Page 18: iPhone, iPad アプリ開発勉強会#2

実際のコードでみてみると...

Hoge *obj = [[Hoge alloc] init];

[obj sayhello] /* メソッド呼び出し */

[obj release]; /* メモリを解放 */

/* または */

[obj autorelease]; /* これもメモリ解放 */

Hogeクラスのオブジェクト

1

リファレンスカウンタオブジェクトが生成された時点で、生成もとのオブジェクトの参照分、1がリファレンスカウンタにセットされます。

12年12月7日金曜日

Page 19: iPhone, iPad アプリ開発勉強会#2

実際のコードでみてみると...

Hoge *obj = [[Hoge alloc] init];

[obj sayhello] /* メソッド呼び出し */

[obj release]; /* メモリを解放 */

/* または */

[obj autorelease]; /* これもメモリ解放 */

Hogeクラスのオブジェクト

0

リファレンスカウンタオブジェクトが生成された時点で、生成もとのオブジェクトの参照分、1がリファレンスカウンタにセットされます。

オブジェクトに対してreleaseメソッドを呼ぶ事でリファレンスカウンタの値が1引かれます。

12年12月7日金曜日

Page 20: iPhone, iPad アプリ開発勉強会#2

実際のコードでみてみると...

Hoge *obj = [[Hoge alloc] init];

[obj sayhello] /* メソッド呼び出し */

[obj release]; /* メモリを解放 */

/* または */

[obj autorelease]; /* これもメモリ解放 */

Hogeクラスのオブジェクト

0

リファレンスカウンタ

オブジェクトに対してreleaseメソッドを呼ぶ事でリファレンスカウンタの値が1引かれます。

12年12月7日金曜日

Page 21: iPhone, iPad アプリ開発勉強会#2

複数のオブジェクトから参照されてると...

Hoge *obj = [[Hoge alloc] init]; /* この時点でリファレンスカウンタは1 */

a.obj = obj; /* この時点でリファレンスカウンタは2 */

b.obj = obj; /* この時点でリファレンスカウンタは3 */

c.obj = obj; /* この時点でリファレンスカウンタは4 */

[obj release]; /* ここで-1されて3 */

....

/* aが解放される時にaがobjに対してreleaseを実行してカウンタは2に */

/* bが解放される時にbがobjに対してreleaseを実行してカウンタは1に */

/* cが解放される時にcがobjに対してreleaseを実行してカウンタは0に */

/* ここでオブジェクトは解放される */

12年12月7日金曜日

Page 22: iPhone, iPad アプリ開発勉強会#2

自動解放プールを使う方法

Hoge *obj = [[Hoge alloc] init];

[obj sayhello] /* メソッド呼び出し */

// [obj release]; /* メモリを解放 */

/* または */

[obj autorelease]; /* これもメモリ解放 */

Hogeクラスのオブジェクト

0

12年12月7日金曜日

Page 23: iPhone, iPad アプリ開発勉強会#2

自動解放プールを使う方法

Hoge *obj = [[Hoge alloc] init];

[obj sayhello] /* メソッド呼び出し */

// [obj release]; /* メモリを解放 */

/* または */

[obj autorelease]; /* これもメモリ解放 */

Hogeクラスのオブジェクト

0

12年12月7日金曜日

Page 24: iPhone, iPad アプリ開発勉強会#2

releaseとautorelease(自動解放プール)の違いは...?

12年12月7日金曜日

Page 25: iPhone, iPad アプリ開発勉強会#2

Hogeクラスのオブジェクト

オブジェクトA

オブジェクトB

オブジェクトC

3

releaseを使うと、カウンタはすぐに-1され、0になった時点でオブジェクト(の使用するメモリは)即時解放されます。

リファレンスカウンタ

release

release

release

12年12月7日金曜日

Page 26: iPhone, iPad アプリ開発勉強会#2

Hogeクラスのオブジェクト

オブジェクトA

オブジェクトB

オブジェクトC

オブジェクトは解放されてなくなりました!リファレンスカウンタが0になったときの

オブジェクトの解放はiOSにより自動的に行われます。

0

リファレンスカウンタ

releaseを使うと、カウンタはすぐに-1され、0になった時点でオブジェクト(の使用するメモリは)即時解放されます。

12年12月7日金曜日

Page 27: iPhone, iPad アプリ開発勉強会#2

Hogeクラスのオブジェクト

オブジェクトA

オブジェクトB

オブジェクトC

3

autoreleaseを使うと、カウンタはすぐには-1されず、従ってオブジェクト(が使用するメモリ)はすぐには解放されません。

リファレンスカウンタ

autorelease

autorelease

autorelease

12年12月7日金曜日

Page 28: iPhone, iPad アプリ開発勉強会#2

Hogeクラスのオブジェクト

オブジェクトA

オブジェクトB

オブジェクトC

3

そのかわり、メモ用紙(自動解放プール)にその旨を記録しておきます。

autorelease

autorelease

autoreleaseオブジェクトAが解放した。オブジェクトBが解放した。オブジェクトCが解放した。

自動解放プール

メモ用紙(自動解放プール)に記録しておく

12年12月7日金曜日

Page 29: iPhone, iPad アプリ開発勉強会#2

Hogeクラスのオブジェクト

オブジェクトA

オブジェクトB

オブジェクトC

3

autoreleaseを使うと、カウンタはすぐには-1されず、従ってオブジェクト(が使用するメモリ)はすぐには解放されません。

オブジェクトAが解放した。オブジェクトBが解放した。オブジェクトCが解放した。

自動解放プール

自動解放プールが解放される時にメモされている「解放」が一斉に行われます。

0

12年12月7日金曜日

Page 30: iPhone, iPad アプリ開発勉強会#2

Hogeクラスのオブジェクト

オブジェクトA

オブジェクトB

オブジェクトC

0

autoreleaseを使うと、カウンタはすぐには-1されず、従ってオブジェクト(が使用するメモリ)はすぐには解放されません。

オブジェクトAが解放した。オブジェクトBが解放した。オブジェクトCが解放した。

自動解放プール

自動解放プールが解放される時にメモされている「解放」が一斉に行われます。

12年12月7日金曜日

Page 31: iPhone, iPad アプリ開発勉強会#2

Hogeクラスのオブジェクト

オブジェクトA

オブジェクトB

オブジェクトC

0

autoreleaseを使うと、カウンタはすぐには-1されず、従ってオブジェクト(が使用するメモリ)はすぐには解放されません。

オブジェクトAが解放した。オブジェクトAが解放した。オブジェクトAが解放した。

自動解放プール

自動解放プールも開放されます...

12年12月7日金曜日

Page 32: iPhone, iPad アプリ開発勉強会#2

どう使い分ければ...

12年12月7日金曜日

Page 33: iPhone, iPad アプリ開発勉強会#2

どう使い分ければ...

メソッドの中でだけ使う、一時的なオブジェクトはメソッドから抜ける前にreleaseで解放します。

- (void) hoge { NSArray * array = [[NSArray alloc] init];

/* 何か処理*/

[array release];}

12年12月7日金曜日

Page 34: iPhone, iPad アプリ開発勉強会#2

どう使い分ければ...

メソッドの返り値として呼び出し元に返す値は、相手が受け取る前に解放してしまってはまずいので、autoreleaseを使います。

- (NSArray *) hoge { NSArray * array = [[NSArray alloc] init]; [array autorelease];

/* 何か処理*/

return array;}

12年12月7日金曜日

Page 35: iPhone, iPad アプリ開発勉強会#2

どう使い分ければ...

なお、次に説明するコンビニエンスコンストラクタを使えばなにもしなくてもautoreleaseを呼び出し済みのオブジェクトが得られます。

- (NSArray *) hoge { NSArray * array = [NSArray array];

/* 何か処理*/

return array;}

12年12月7日金曜日

Page 36: iPhone, iPad アプリ開発勉強会#2

ちなみに、最も基本的なオブジェクト生成は

[[クラス名 alloc] init];

で、この場合はreleaseまたはautoreleaseを明示的に呼んで解放してやる必要があります。

ただし、これとは別に

[クラス名 小文字ではじまるクラス名~];

というオブジェクト生成方法もあり、この場合は既にautoreleaseが呼ばれた状態でオブジェクトが渡されます。

つまり...

NSArray *array = [NSArray array];

NSArray * array = [[NSArray alloc] init][array autorelease];

と同じです。

12年12月7日金曜日

Page 37: iPhone, iPad アプリ開発勉強会#2

ARC (オート・レファレンス・カウンタ)とは

12年12月7日金曜日

Page 38: iPhone, iPad アプリ開発勉強会#2

iOS5から、ARCが使えるようになりました

12年12月7日金曜日

Page 39: iPhone, iPad アプリ開発勉強会#2

ARCを使ってもオブジェクトの解放に関する考え方は変わりませんが...

12年12月7日金曜日

Page 40: iPhone, iPad アプリ開発勉強会#2

- (void) hoge { NSArray * array = [[NSArray alloc] init];

/* 何か処理*/

[array release];}

ARC無しの場合

使い終わったらreleaseしてやらないとメモリリーク!

12年12月7日金曜日

Page 41: iPhone, iPad アプリ開発勉強会#2

- (void) hoge { NSArray * array = [[NSArray alloc] init];

/* 何か処理*/

}

ARCが有効の場合

と書いておけば...

- (void) hoge { NSArray * array = [[NSArray alloc] init];

/* 何か処理*/

[array release];}

コンパイル時にコンパイラが勝手に追加してくれます!

メモリにも開発者にも優しい(*´∀`*)

コンパイル

12年12月7日金曜日

Page 42: iPhone, iPad アプリ開発勉強会#2

今後はARCを有効にしておいて、[[クラス alloc] init] でオブジェクトを生成しても解放忘れがなく、

かつARCによって自動挿入されたreleaseにより、すぐにオブジェクトを解放してくれるのでこっちがいいかも。

12年12月7日金曜日

Page 43: iPhone, iPad アプリ開発勉強会#2

RubyやJavaのGCとの違いは?

GC(ガベージコレクション)はアプリ実行時に一定期間おきにメモリの掃除をします。

ARCは、コンパイル時にメモリの解放コードを自動挿入し、実行時には自動的に何かをする事はありません。

GCが走らない分、処理が止まったりせず、より滑らかでスムーズな使用感が得られます!

12年12月7日金曜日

Page 44: iPhone, iPad アプリ開発勉強会#2

おわり

12年12月7日金曜日