29
第14回iPhone輪講 『私にも見えました』(20歳/学生)

Objc05

Embed Size (px)

Citation preview

第14回iPhone輪講

『私にも見えました』(20歳/学生)

CHAPTER08Foundationフレームワークの重要なクラス

オブジェクトの変更可能性

一旦生成したインスタンスの属性が,後から変更可能な(mutable)クラスと,変更不可能な(immutable)クラスがある

インスタンスを後から変更できる性質の事を変更可能性(mutability)と呼ぶ事がある

例えば文字列では…

不変なインスタンスを作る→NSString

可変なインスタンスを作る→NSMutableString

可変なオブジェクトと不変なオブジェクト

Foundationフレームワーク内の主な可変,不変なクラスのペア

種類 不変なクラス 可変なクラス

配列 NSArray NSMutableArray

データ NSData NSMutableData

辞書 NSDictionary NSMutableDictionary

集合 NSSet NSMutableSet

文字列 NSString NSMutableString

属性付き文字列 NSAttributedString NSMutableAttributedString

文字集合 NSChapterSet NSMutableChapterSet

インデックス集合 NSIndexSet NSMutableIndexSet

可変なオブジェクトの作成

表のペアは,すべて可変なクラスが不変なクラスのサブクラスになっている

可変なクラスのインスタンスは,不変なクラスのインスタンスと同じ動作をする事が出来る

可変なオブジェクトの作成

不変なオブジェクトを可変なオブジェクトとして扱いたい場合

mutableCopyというメソッドを使って,可変なコピーを作成する

不変なクラスと可変なクラスがペアで用意されているクラスであれば利用できる

可変なオブジェクトの生成

不変なクラスのインスタンスに対しmutableCopyを送る

レシーバと同じ内容の可変なクラスのインスタンスが生成される

新しく生成されたインスタンスのオーナーはmutableCopyのセンダ

- (id)mutableCopy

コレクション

コレクションとはデータをまとめて管理する仕組みの事

ObjCのコレクションクラスには

NSArray / NSMutableArray

NSDictionary / NSMutableDictionary

NSSet / NSMutableSet

などがある

NSArray

NSArrayは個々のデータ配列を要素として管理してまとめる

各要素には0から始まるインデックスがつく

各要素にはそのインデックスを指定してアクセスする

各要素にはオブジェクトのポインタなら,どの種類のオブジェクトのポインタでも格納する事が出来る

NSDictionary

NSDictionaryはキー(key)と値(value)をペアとして管理する

ひとつのペアの事をエントリ(entry)と呼ぶ

エントリのキーには通常は文字列が使われる

エントリは1つのNSDictionaryに複数登録できる

namelyricsmusic

“LIBERTY”“Salyu”“Tatsuya Kokufu”

キー 値

namelyricsmusic

“Dialogue”(“Salyu”,”Takeshi Kobayashi”)“Takeshi Kobayashi”

NSDictionary

NSArrayは要素にインデックスを付けて管理していた

NSDictionaryでは各要素に名前をつけて管理している

NSSet

NSSetはNSArrayやNSDictionaryと同じでオブジェクトの集合をまとめる

NSArrayなどと違い各要素に順序という概念が無い

インデックスやキーを付けて個々の要素を管理することは出来ない

同じ要素が複数含まれる事は無い

コンビニエンスコンストラクタ

一時的なインスタンスを簡便に生成するメソッドをObjCではコンビニエンスコンストラクタと呼ぶ

典型的にはallocとイニシャライザ,autoreleaseを呼び出してインスタンスを返すようなクラスメソッド

コンビニエンスコンストラクタ

クラスメソッドfractionWithNumerator:denominator:は,新たなインスタンスを作成

イニシャライザinitWithNumerator:denominator:で,初期化した後,autoreleaseを適用して返す

+ (id)fractionWithNumerator:(int)n denominator:(int)d{ id f = [[self alloc] initWithNumerator:n denominator:d]; return [f autorelease];}

高速列挙

ObjC2.0では配列や集合などのコレクションに格納されている要素のオブジェクトを繰り返し順番に取り出す為の構文が使えるようになった

この機能を高速列挙と呼ぶ

高速列挙

変数groupがコレクションオブジェクトだとすると,以下の構文でgroupの全要素を順に取り出し表示できる

groupの内容自体に変化は無い

id obj;for (obj in group) { printf(“%s\n”, [[obj description] UTF8String]);}

高速列挙

for...inの構文は以下の構造をしている

変数はオブジェクトを格納できる型を持つ必要がある

コレクション式はコレクションオブジェクトを格納した変数か,値がコレクションになる式でなければならない

コレクション式はループ実行開始前に1回だけ評価される

for ( 変数 in コレクション式 ) { /* 何らかの処理 */}

高速列挙

コレクションは不変でも可変でも構わない

可変の場合ループを実行している間に内容を変更してはいけない

➡変更されると実行が中断される

高速列挙

コレクションが配列の場合

先頭から要素が取り出される

集合の場合

取り出される順序は内部表現に依存する

辞書オブジェクトの場合

取り出されるのはキー

取り出される順序は内部表現に依存する

列挙子NSEnumerator

列挙子とは配列や集合,辞書などのコレクションに格納されている要素のオブジェクトに順番にアクセスするための機構

ObjC2.0以降では列挙子を使うよりfor...inの構文の高速列挙を用いる方が便利

高速列挙の利点

高速列挙を使用する利点はいくつかある

列挙子NSEnumeratorを使うなどの手法より遥かに効率がいい

構文が簡単

安全である

列挙子には変更防止機能があるので,列挙中にコレクションを変更しようとすると例外が発生する

高速列挙と列挙子

このfor...inの構文は,コレクションから得た列挙子を使って,そのコレクションの要素を順番に取り出す

for ( 変数 in 列挙子) { /* 何らかの処理 */}

高速列挙と列挙子

- (NSEnumerator *)reverseObjectEnumerator

要素に逆順にアクセスする為の列挙子を返す

上記のように書けばfor...inの構文を使って逆順に処理を行うことが出来る

enumerator = [myarray reverseObjectEnumerator];for (obj in enumerator) { /* 何らかの処理 */}

弱い参照を使えるコレクションクラス

ガーベジコレクションを利用する場合,弱い参照でオブジェクトが格納されているコレクションオブジェクトを使う事が出来る

要素のオブジェクトを格納するために,強い参照を使っているコレクションオブジェクト➡コレクション自体が不要にならない限り,要素オブジェクトは解放される事は無い

弱い参照を使えるコレクションクラス

次で説明するコレクションクラスはオプションとして弱い参照を使う事を選択できる➡コレクションに格納されていたとしても不要になったオブジェクトは回収され,コレクションからも削除される

NSPointerArray

NSPointerArrayはNSArrayに似た配列オブジェクトのクラス

NSArrayと継承関係はない

可変なコレクション

オブジェクトだけでなく,NULLも含む任意のデータへのポインタを含む事が出来る

NSHashTable

NSHashTableはNSMutableSetに似た可変な集合オブジェクトのクラス

NSMutableSetと継承関係はない

弱い参照で要素オブジェクトが参照できる点以外はNSMutableSetと非常によく似ている

NSMapTable

NSMapTableはNSDictionaryに似た可変な辞書オブジェクトのクラス

NSDictionaryと継承関係はない

キーと値のどちらか,または両方に弱い参照を使える

ガーベジコレクションによってキーと値のどちらかが解放された場合,そのエントリは辞書から削除される

おわり