Suche senden
Hochladen
Objc03 1
•
0 gefällt mir
•
207 views
H
hasegawa
Folgen
Melden
Teilen
Melden
Teilen
1 von 62
Jetzt herunterladen
Downloaden Sie, um offline zu lesen
Empfohlen
Objc04
Objc04
hasegawa
Objc03 2
Objc03 2
hasegawa
Cocoa Pro09
Cocoa Pro09
hasegawa
Objc05
Objc05
hasegawa
Objc02
Objc02
hasegawa
Cocoa Pro6
Cocoa Pro6
hasegawa
Midterm2nd
Midterm2nd
hasegawa
Objc01
Objc01
hasegawa
Weitere ähnliche Inhalte
Mehr von hasegawa
Cocoa Pro08
Cocoa Pro08
hasegawa
Cocoa Pro07
Cocoa Pro07
hasegawa
Cocoa Pro5
Cocoa Pro5
hasegawa
Cocoa Pro4
Cocoa Pro4
hasegawa
Cocoa Pro01
Cocoa Pro01
hasegawa
Cocoa Pro03
Cocoa Pro03
hasegawa
CocoaPro02
CocoaPro02
hasegawa
Mehr von hasegawa
(7)
Cocoa Pro08
Cocoa Pro08
Cocoa Pro07
Cocoa Pro07
Cocoa Pro5
Cocoa Pro5
Cocoa Pro4
Cocoa Pro4
Cocoa Pro01
Cocoa Pro01
Cocoa Pro03
Cocoa Pro03
CocoaPro02
CocoaPro02
Objc03 1
1.
iPhone輪講 第12回
2.
CHAPTER05 リファレンスカウンタを用いた メモリ管理方式
3.
C言語の場合malloc()などを用いて自前でメモリ管理を行わなけ ればならない 確保したメモリ領域は,プログラム終了時点で自動的に 解放される しかし,小規模な使い捨てのプログラムでない限り, メモリ領域は不要になった時点で解放する必要がある メモリ管理の必要性
4.
メモリ管理の必要性 不要になったが,不注意やプログラム上の不備から,メモリ領域 が解放されずそのまま残る事がある 解放し損なった領域は,それぞれが小さいものでも積み重なり やがてメモリ空間を圧迫するようになる ‣ プログラムの動作が極端に遅くなったり,システム全体の進行 が滞ったりする ‣ このような解放漏れをメモリリークという
5.
メモリ管理の必要性 一旦解放したメモリ領域に後から誤ってアクセスしてしまう この場合プログラムが誤作動したり,異常終了したりする事が ある 既に解放された場所を指す危険なポインタを ぶらさがりポインタと呼ぶ
6.
カウンタ管理方式 Cocoa環境のObjCでは動的なメモリ管理のために リファレンスカウンタを利用する方式が用意されている 各インスタンスオブジェクトごとに,それが何ヶ所から参照 されているかを示すカウンタを用意する どこからも参照されなくなったときに解放する カウンタの操作はプログラマがコード中で指定しなければ ならない
7.
ガーベジコレクション ObjC2.0ではカウンタ管理方式とは別にガベージコレクション というメモリ管理方法も利用できる ガベージコレクションではプログラムの通常の実行とは 別に不要になったオブジェクトを探すためのルーチンが 自動的に動作して解放が行われる カウンタ操作のような手間が無い分プログラムの作成が 容易
8.
リファレンスカウンタ リファレンスカウンタとは,そのインスタンスが何ヶ所から参照 されているか(プログラム中の何ヶ所でそのオブジェクトを必要 としているか)示すもの
9.
リファレンスカウンタ allocで生成されイニシャライザで初期化されたインスタンスは それを生成したメソッドを持つオブジェクトから参照されている リファレンスカウンタは1となる
10.
リファレンスカウンタ あるオブジェクトAがインスタンスBを参照しながら処理を 進めるとする インスタンスBが別のオブジェクトから勝手に解放されてしま わないよう,オブジェクトAはインスタンスBに対して retainというメッセージを送る retainを実行するたび,インスタンスのリファレンスカウン タは1ずつ増加する
11.
リファレンスカウンタ インスタンスが不要になったらreleaseというメッセージを送る reelaseはインスタンスのリファレンスカウンタを1ずつ 減らすように働く
12.
リファレンスカウンタ 実際にインスタンスオブジェクトを解放するのはdeallocという メソッド releaseが送られ,リファレンスカウンタが0になった時点で deallocが呼び出されインスタンスは解放される 通常はdeallocというメソッドをプログラム内から 直接呼び出してはいけない
13.
リファレンスカウンタ retain,release,deallocは以下のように宣言する retainはレシーバ自身を返り値にする - (id)retain - (oneway
void)release - (void)dealloc
14.
リファレンスカウンタ インスタンスにretainを送る事を「インスタンスを保持する」 という インスタンスを生成したりインスタンスを保持している状態を そのインスタンスに対する「オーナーシップを持っている」と いう オーナーシップを持つオブジェクトを,そのインスタンスの オーナーと呼ぶ
15.
リファレンスカウンタ 図5-1:リファレンスカウンタを利用してない例 オブジェクトA オブジェクトB 1 1 0 オブジェクトA オブジェクトB オブジェクトA オブジェクトB alloc+init
release (1)オブジェクトAが インスタンスを生成 (2)オブジェクトBが インスタンスを参照 (3)オブジェクトAが インスタンスの利用をやめる
16.
リファレンスカウンタ (1)ではオブジェクトAの メソッドの中で,あるインスタ ンスが生成されてオブジェクトA のインスタンス変数から 参照するようになったとする オブジェクトA オブジェクトB 1 alloc+init (1)オブジェクトAが インスタンスを生成 インスタンス
17.
リファレンスカウンタ インスタンスの持つ リファレンスカウンタの値は1で オブジェクトAがオーナーである とみなせる オブジェクトA オブジェクトB 1 alloc+init (1)オブジェクトAが インスタンスを生成 オーナー
18.
リファレンスカウンタ 次にこのインスタンスへの ポインタがオブジェクトBに 渡され,オブジェクトBも同様に インスタンス変数から参照する ようになる 1 オブジェクトA オブジェクトB (2)オブジェクトBが インスタンスを参照
19.
リファレンスカウンタ しかし,オブジェクトBはretain を送らないので,インスタンス のオーナーでなくリファレンスカ ウンタも1のまま 1 オブジェクトA オブジェクトB (2)オブジェクトBが インスタンスを参照
20.
リファレンスカウンタ オブジェクトAはもうこのインス タンスを使わなくなったため releaseメッセージを送信する 0 オブジェクトA オブジェクトB release (3)オブジェクトAが インスタンスの利用をやめる
21.
リファレンスカウンタ オブジェクトAはもうこのインス タンスを使わなくなったため releaseメッセージを送信する 0 オブジェクトA オブジェクトB release (3)オブジェクトAが インスタンスの利用をやめる
22.
リファレンスカウンタ オブジェクトAはもうこのインス タンスを使わなくなったため releaseメッセージを送信する オブジェクトBから参照されて いるにも関わらず,インスタ ンスは解放される 0 オブジェクトA オブジェクトB release (3)オブジェクトAが インスタンスの利用をやめる
23.
リファレンスカウンタ このような事を防止するには 動的に生成されたインスタンスに対し,それを参照する側の オブジェクトがretainを送っていなければならない retainを送る事により,そのインスタンスのオーナーとなり リファレンスカウンタを増やして,使用中にインスタンスが 解放されないようにする
24.
リファレンスカウンタ 図5-2:リファレンスカウンタを利用した例 オブジェクトA オブジェクトB 1 2 1 オブジェクトA オブジェクトB オブジェクトA オブジェクトB alloc+init
release retain (1)オブジェクトAが インスタンスを生成 (2)オブジェクトBが インスタンスを参照 (3)オブジェクトAが インスタンスの利用をやめる
25.
リファレンスカウンタ (2)でオブジェクトBがインス タンスを参照すると同時に retainを送ってインスタンスを 保持する この時点でリファレンスカ ウンタは2になる 2 オブジェクトA オブジェクトB retain (2)オブジェクトBが インスタンスを参照
26.
リファレンスカウンタ オブジェクトAがreleaseを送信 してオーナーシップを放棄しても インスタンスは解放されない オブジェクトBはその後も このインスタンスを使う事が 出来る 1 オブジェクトA オブジェクトB release (3)オブジェクトAが インスタンスの利用をやめる
27.
インスタンス解放のための メソッド定義 オーナーシップを放棄するにはオブジェクトにreleaseを送る 実際にインスタンスに割り当てられたメモリ領域が解放される 時にはdeallocというメソッドが実行される
28.
インスタンス解放のための メソッド定義 あるインスタンスを解放する 保持していたオーナーシップを放棄するには ‣ スーパークラスのdeallocのメソッドを上書き ‣ その中でそのクラス固有のインスタンスに対してrelease メッセージを送る
29.
インスタンス解放のための メソッド定義 releaseのメソッドを上書きしてはいけない 実際に解放されるのはdeallocが呼び出されたとき 後始末はすべてそこで行う
30.
インスタンス解放のための メソッド定義 上書きしたメソッドの中で まずインスタンスを解放す る直前にすべき後始末の コードを記述する - (void)dealloc //deallocを上書き { /* ここでサブクラスに固有の インスタンス変数の オーナーシップをreleaseを使って 放棄する その他の「後始末」のコードもここに 書く */ [super
dealloc]; }
31.
インスタンス解放のための メソッド定義 通常はそのサブクラスのイ ンスタンス変数に対応する オブジェクトのオーナー シップをreleaseを使って 放棄する - (void)dealloc //deallocを上書き { /* ここでサブクラスに固有の インスタンス変数の オーナーシップをreleaseを使って 放棄する その他の「後始末」のコードもここに 書く */ [super
dealloc]; }
32.
インスタンス解放のための メソッド定義 その後でスーパークラスの deallocメソッドを呼びだし その他のインスタンス変数 の処理やメモリ領域の解放 を任せる - (void)dealloc //deallocを上書き { /* ここでサブクラスに固有の インスタンス変数の オーナーシップをreleaseを使って 放棄する その他の「後始末」のコードもここに 書く */ [super
dealloc]; }
33.
インスタンスの自動解放 実際のプログラミングでは,一時的にだけ利用して,あとは不要 となるオブジェクトを多数使う事は少なくない そのような一時的なインスタンスを毎回忘れずに解放するのは 面倒
34.
インスタンスの自動解放 Cocoa環境のObjCにはインスタンスの自動解放という仕組みが 用意されている 自動解放をおこなうには,まずNSAutoreleasePoolのインス タンスを作る このインスタンスを自動解放プールと呼ぶ
35.
インスタンスの自動解放 その状態でautoreleaseメソッドを呼び出すと,そのインスタ ンスが自動解放プールに登録される この時点ではインスタンスは解放されない,リファレンスカ ウンタの値も変化しない 最後に自動解放プールを解放すると,登録されているすべての releaseメソッドを呼び出す
36.
インスタンスの自動解放 autoreleaseは以下のように宣言される 自動解放プールに登録され,事実上はオーナ湿布を放棄されて いるオブジェクトを一時的なオブジェクトと呼ぶ事にする - (id)autorelease;
37.
インスタンスの自動解放 自動解放プールの典型的な使い方 id pool =
[[NSAutoreleasePool alloc]init]; /* ここで一連の作業を行う 一時的に用いられるインスタンスにはautorelease メッセージを送っておく */ [pool release]; /*インスタンスはここで解放される */
38.
自動解放プールの使い方の注意 自動解放プールのインスタンスは複数作成できる 複数の自動解放プールが存在する場合,最も最近作成されたも のが有効なものとして機能する
39.
自動解放プールの使い方の注意 長時間実行されるルーチンや,一時的なインスタンスを多く使う ルーチンでは局所的に自動解放プールを利用し,メモリ資源がよ り有効に使われるようにプログラムを記述する
40.
自動解放プールの使い方の注意 何回も繰り返されるループ内で一時的なインスタンスが数多く使 われるような場合 ループの最初で自動解放プールを作成し,ループの最後で解放 する while (...) { id
pool = [[NSAutoreleasePool alloc]init]; /* ここで一連の作業を行う */ [pool release]; /*インスタンスはここで解放される */ }
41.
イベントループと 自動解放プール マウスやキーボードの操作が行われたという情報はイベントと 呼ばれる アプリケーションは発生したイベントを次々に取り出しては それに対応する処理を行うという動作を繰り返す この繰り返し動作はイベントループと呼ばれる CocoaのGUIを用いたアプリケーションではNSApplication というクラスがイベントループの管理を行う
42.
イベントループと 自動解放プール 例えばあるボタンがクリックされる ‣ NSApplicationのインスタンスがそのイベントを検知する ‣ ボタンのクリックに対応したメッセージがあらかじめ指定 したオブジェクトに送られて処理が行われる
43.
イベントループと 自動解放プール NSApplicationはイベントループの各処理の前に自動解放ループ を作成し,処理ルーチンの実行が終わった後で自動解放プールを 解放する CocoaのGUIを利用したプログラミングでは,自動解放プール の管理に気を使うことなく,一時的なインスタンスを自由に 使う事が出来る
44.
オーナーシップ・ポリシー オーナーシップ・ポリシーとは 「インスタンスイブジェクとのオーナーが,そのインスタンス の解放に関して責任を持つ」とする取り決めの事 言語上の決まりでなく,マナーのようなもの
45.
オーナーシップ・ポリシー オブジェクトが別のオブジェクトのオーナーになるとき alloc...によるインスタンス生成 クラスに対してallocで始まるクラスメソッドを送ってイン スタンスを生成した場合 あるいはnew...で始まるクラスメソッドを送って インスタンスを生成した場合
46.
オーナーシップ・ポリシー copy...によるインスタンスのコピー あるインスタンスに対してcopyで始まるメソッドを送って インスタンスの複製を生成した場合 retainによる保持 あるインスタンスにretainメッセージを送って保持した場合
47.
オーナーシップと オブジェクト間の関係 プログラムを複数のオブジェクトから構成するとき, どのオブジェクトがどのオブジェクトのオーナーとなるべきか 決めておく必要がある 容易に決定できる場合と,そうでない場合がある
48.
オーナーシップと オブジェクト間の関係 図:オブジェクト間の参照関係 B A C E D F B A C D (1)階層的な包含関係を 持つ場合 (2)ネットワーク的な参照関係を 持つ場合
49.
オーナーシップと オブジェクト間の関係 (1)は親とも言うべきオブ ジェクトが子に相当する オブジェクトを保持すると いう階層的な関係となって いる場合 B A C E D F (1)階層的な包含関係を 持つ場合
50.
オーナーシップと オブジェクト間の関係 オブジェクトAはB,C,D のオーナーであり, DはE,Fのオーナーである と考える B A C E D F (1)階層的な包含関係を 持つ場合
51.
オーナーシップと オブジェクト間の関係 Aを解放するときにはA自体 の解放に先立ってB,C,D を解放する Dを解放するには,まず E,Fを解放するという 順番になる B A C E D F (1)階層的な包含関係を 持つ場合
52.
オーナーシップと オブジェクト間の関係 CからA,FからDに点線矢 印がのびている 自分の親に相当するオブ ジェクトを参照するため のポインタで バックポインタと呼ばれ る B A C E D F (1)階層的な包含関係を 持つ場合
53.
オーナーシップと オブジェクト間の関係 (2)は複数のオブジェクトが 比較的対等な立場で相互に 参照し合っている例 B A C D (2)ネットワーク的な参照関係を 持つ場合
54.
オーナーシップと オブジェクト間の関係 すべての参照関係にオーナー シップが伴っていると 容易に保持の循環問題が発 生する B A C D (2)ネットワーク的な参照関係を 持つ場合
55.
オーナーシップと オブジェクト間の関係 オーナーシップを伴わない 参照関係の場合,注意しな いと知らないうちに相手が 解放されてしまう B A C D (2)ネットワーク的な参照関係を 持つ場合
56.
オーナーシップと オブジェクト間の関係 いずれにせよオーナーシップを保持するインスタンス変数と ポインタを参照するだけのインスタンス変数があった場合 その区別を厳密に行わなければメモリリークが発生する 原因となる
57.
一時的なインスタンスの生成 一時的に使われる事を前提に,オーナーを持たない形で生成され るインスタンスもある 生成直後に自動解放プールに登録する事で実現される
58.
一時的なインスタンスの生成 文字列を表すためのNSStringがある 文字コードがUnicode(UTF8)のCの文字列からNSString のインスタンスを生成することができる
59.
一時的なインスタンスの生成 以下の2つがある allocで生成したインスタンスに対するイニシャライザ 生成したオブジェクトがインスタンスのオーナーになる 一時的なインスタンスを生成するためのクラスメソッド 結果として返されるインスタンスは自動解放プールに 登録される - (id)initWithUTF8String:(const char
*)bytes - (id)stringWithUTF8String:(const char *)bytes
60.
一時的なインスタンスの生成 一時的なインスタンスを生成するクラスメソッドをもつクラスは 他にもある 一般にこれらのメソッドはinitではなく,生成されるデータを 表す名前から始まる約束がある NSStringならメソッド名はstring...から始まる - (id)stringWithUTF8String:(const char
*)bytes
61.
解放しないオブジェクト オブジェクトによっては解放しなくてよいものもある クラスオブジェクトや,1つのインスタンスだけ共有して 使うもの,NSString文字列になるようなオブジェクト定数
62.
解放しないオブジェクト 解放してほしくないオブジェクトを定義するには クラス定義でメソッドretain,release,およびretainCountを 書き換える 具体的にはretainとrelease,autoreleaseが何もしないように 上書きし,リファレンスカウンタの値が変更されないように する
Jetzt herunterladen