CHAPTER08 Foundationフレームワークの重要なクラス
2011/09/14(水) 17:44 Objective-C親記事へこのエントリーをはてなブックマークに追加

immutableなオブジェクトとmutableなオブジェクト

可変なオブジェクト、不変なオブジェクトが存在するのは、
不変なオブジェクトはデータ構造が簡潔であり処理も軽くなります。
可変なオブジェクトはある程度拡張を考えていくため、データ構造が複雑になったりします。
不変なオブジェクトに対してデータを追加するというのはオブジェクトをまるごとコピーすることが必要となるため、大きな不変なオブジェクトに対しては処理も大きくなってしまいます。
可変なオブジェクトの場合は自動的に拡張できるため追加していくような処理に向いています。
このように2つの性質を持ったオブジェクトを処理内容によって使い分けしていきます。

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

NSMutableXXX は可変なクラスとなっていて、これらの可変なクラスは不変なクラスのサブクラスとして実装されている。
不変なクラスのオブジェクトをまるごとコピーして可変なオブジェクトに変更することもできる
不変なクラスのインスタンス -> 可変なクラスのインスタンス
-(id) mutableCopy
というインスタンスメソッドを使用する事で可変なインスタンスを返す。

文字列クラス

> @""
というように文字列定数(文字列オブジェクトのオブジェクト定数)を書くと、
nilではなくて長さが0の文字列を表現できる。
文字列定数はプログラム開始から終了まで存在し続けてreleaseやガーベッジコレクションで解放されることはない。

NSString

(3)書式に従った文字列作成
NSStringではprintfのようなフォーマットで文字列を作成できる。
このうちの%@というのは対象のオブジェクトのdescriptionメソッドを呼び出した結果を埋め込んでいる。
descriptionはNSObjectで定義されているため、任意のオブジェクトを対象にできるが何を返すかはラクスの実装次第になる。

(10)パスの操作
文字列がファイル名のパス名を表現しているときに便利に使えるメソッドも用意されている。
NSPathUtilities.hに定義されていて、パスの分解して、ファイル名や拡張子を取り出したり絶対パス7日を判定したりできるメソッドがある。

NSData

バイト列からなるデータを扱う標準のクラス。
任意のバイト列をオブジェクトとして扱うラッパクラス。

NSArray

配列クラス
(7)ファイル入出力
ファイルの入出力はプロパティリストの形式で行われる。
writeToFileなどファイルに出力出来る。

配列オブジェクトとオーナーシップ

配列にはオブジェクトも入れることができるため、次のように書く複数のオーナーシップを持ってしまい解放することが困難になります。
NSArray *arr =[[NSArray alloc] initWithObjects:
	[[Card alloc] init], [[Player alloc] init], nil];
このコードを実行したオブエジェクトはCard,Playerのインスタンスのオーナーになり、配列arrについてのオーナーにもなります。
arrも要素のオーナーを持つことになるので、arrが解放されるときarrの中のオブジェクトそれぞれに対してreleaseが呼ばれます。そのため、arrを解放しても、arrが持っていたオーナーシップは放棄できますが、オブジェクトが持っている2つの要素のオーナーシップは残ったままになってしまう。

なので、autoreleaseして要素に指定するか、一旦変数に保持してから要素に指定する必要があります。
NSArray *arr =[[NSArray alloc] initWithObjects:
	[[[Card alloc] init] autorelease], [[[Player alloc] init] autorelease], nil];

// or

id card = [[Card alloc] init]; 
id player = [[Player alloc] init]; 
NSArray *arr =[[NSArray alloc] initWithObjects: card, plyaer, nil];
[card release];
[player release];
このようなオブジェクトを格納するためのクラスはコレクションといったりして、配列の他に集合オブジェクト、辞書オブジェクトがある。

高速列挙

配列や集合、辞書で格納する要素のオブジェクトを順番に取り出すためにfor...in構文による高速列挙というものがある。
for...in中では内容の変更はしてはいけなくて、辞書オブジェクトの高速列挙の取り出し順は内部実現に依存する。
列挙子 NSEnumerator
列挙子を使うことでもfor...inと同じように、列挙ループを行うことができる。
高速列挙と列挙子
高速列挙と呼ばれる所以は列挙子のように毎回メソッドを呼ばなくても列挙ができるため、for...inの方が高速であるからそういう。
列挙子はいらない子なのかというと、それは別の話で列挙子は列挙方法も指定できるため、次のように要素を逆順に取り出すなども行える。
enumerator = [myarray reverseObjectEnumerator];
for(obj in enumerator){
// fooo
}
また条件によって要素を読み飛ばしたり柔軟な判断もできる。
高速列挙はNSFasEnumerationプロトコルを実装しているクラスで使用できるようになっている。

集合クラス

NSSet
配列とは異なり、要素間での順番がなく、同じ要素が複数含まれないようなコレクションを集合オブジェクトと呼ぶ。cocoaではNSSetクラスで定義されている。
NSMutableSetのサブクラスとしてNSCountedSetという可変集合のクラスがあり、これは同じオブジェクトを複数回含むことができ、このクラスをカウント付き集合、バッグ(bag)と呼ぶ

辞書クラス

key valueなデータ構造を持ったNSDictionaryクラス。
NSDictionaryはクラスクラスタとして提供されているため、通常の方法だとサブクラスが作成できないことに注意しておく。

オブジェクト型ではないものを値に指定する場合はNSNumberやNSNull,NSValueなどのラッパクラスをできるだけ使う。

数値に対するラッパクラス

メソッドの引数にオブジェクト型を要求されることは多くの場面であるので、そういう時にラッパクラスが便利に使える。

NSNumber

NSNumberはそれぞれの方に対して生成メソッドなどがある
- initWith~
- initWithBool;
+ numberWith~
+ numberWithInt;
NSNumber型から値を参照するにはintegerValueインスタンスメソッドを使って取り出せる。

NSValueも大体同じ。

NSNull

配列などに要素としてnilを含めることはできない(末端を表してるから)
なので、NSNullを使い空のオブジェクトを表現する。
+ (NSNull *) null;
NSNullのインスタンスを返しますが、この返されるオブジェクトは常に同一のオブジェクトになる。
そのため obj == [NSNull null] でNSNullなのかを判定できる。

NSURL

URLやパスを扱うクラス。
ファイルのパスをNSURLで指定するメソッドも多い。

名前:  非公開コメント   

  • TB-URL  http://efcl.info/adiary/0132/tb/