【コラム】
以前のObjective-Cでは、列挙子を実現するためにNSEnumeratorが使われていた。NSEnumeratorはクラスであり、nextObjectという次のオブジェクトを取得するためのメソッドが定義されていた。
Objective-C 2.0のFast Enumerationでは、この機能を実現するためにNSFastEnumerationというものを使う。これはプロトコルになる。このプロトコルに準拠しているコレクションクラスに対して、例のfor文による列挙が使えるわけだ。ちなみに、NSArray、NSDictionary、NSSet、NSHashTable、NSMapTableといった、主なコレクションクラスで準拠している。
NSFastEnumerationプロトコルの定義は、次のようなものになる。
typedef struct {
unsigned long state;
id* itemsPtr;
unsigned long* mutationsPtr;
unsigned long extra[5];
} NSFastEnumerationState;
@protocol NSFastEnumeration
- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState*)state objects:(id*)stackbuf count:(NSUInteger)len;
@end
まず、NSFastEnuemrationStateという構造体が定義されている。これは、列挙の状態を記述するものになる。そして、countByEnumeratingWithState:objects:count:というメソッドがある。これが、Fast Enumerationの中核となるメソッドのはずだ。
さて、このメソッドの使われ方だが、これだけを見ていてもどうにもわからない。ここは真っ当に、Appleが公開しているドキュメントをあたることにしよう。ここからは、『Objective-C 2.0プログラミング言語: 高速列挙』のドキュメントをもとに話を進めていく。
まずは、このメソッドがどのように使われているかを調べてみよう。for文を使った次のようなソースコード、
for ( existingItem in expression ) {
stmts
}
は、次のようにコンパイルによって変換されることになる。
{
id elem;
NSFastEnumerationState __enumState = { 0 };
id __items[16];
unsigned long __limit =
[collection countByEnumeratingWithState:&__enumState objects:__items count:16];
unsigned __counter = 0;
unsigned long __startMutations = * __enumState.mutationsPtr;
if (__limit) do {
__counter = 0;
do {
if (__startMutations != * __enumState.mutationsPtr) objc_enumerationMutation(); // 引数不足?
elem = __enumState.itemsPtr[__counter++];
stmts;
} while (__counter < __limit);
} while (__limit = [collection countByEnumeratingWithState:&__enumState objects:__items count:16]);
};
このソースコードは、先ほどのドキュメントのページからコピーしたものから、若干の文法エラーを修正したものだ。ただし、まだ問題が残っている。14行目にあるobjc_enumerationMutation()の呼び出しだ。これはランタイム関数であるが、ヘッダファイル(objc/runtime.h)によると、プロトタイプ宣言は次のようになっている。
OBJC_EXPORT void objc_enumerationMutation(id)
AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER;
id型の引数を1つ取るらしい。だが、ソースコードでは引数は指定されていない。この関数は、ランタイムの中でもプライベート関数となるらしく、挙動についての説明がない。よって憶測にならざるを得ないのだが、前後の関係から見て、__enumState.mutationsPtrを渡すことになるのではないだろうか?
次回は、このソースコードの挙動について調べてみよう。
| 理研、脳・脊髄形成に必要な神経板湾曲の仕組みを解明 [20:16 5/25] |
| 京大、「慢性閉塞性肺疾患」患者の労作時呼吸困難は鍼治療が有効と実証 [20:08 5/25] |
| 120Hz SHVカメラ用イメージセンサーを使った撮像装置 - SHVフルスペック化へ [18:10 5/25] |
| 京大、視覚による物体認知は前頭前野からのトップダウン信号が重要と確認 [17:45 5/25] |
| 製品数の拡大だけでなくBCPの展開なども含めた総合力で事業の強化を図るTI [17:25 5/25] |
|
[9nine]制服姿見納め? セーラー服で登場も川島海荷「4人はコスプレ」 [19:15 5/27] エンタメ |
|
「NO.6」4巻は書き下ろしドラマCD付、木乃のサイン会も [18:49 5/27] ホビー |
|
[今週の新刊]マンガ大賞3回ノミネート「アイアムアヒーロー」 カープ愛「球場ラヴァーズ」も [18:33 5/27] ホビー |
|
「ゆりてつ」サイン会は作者と都電に揺られるツアー仕立て [17:45 5/27] ホビー |
|
【ネタバレもありの徹底解明コラム】『サザエさん』タマの意外な事実 [17:30 5/27] ホビー |
4つの診断で、自分の適性を見つめなおそう!
働くこと・挑戦し続けることへの思いを綴ったインタビュー
あなたにピッタリのアドバイスを読むことができます。
転職に必要な情報が収集できます
企業からアプローチのメッセージが届きます。