2010年5月22日土曜日

Objective-Cにおける高速列挙

if分に見慣れない構文
   if ( (id)oneObject in nib)
があったので、調べてみると、高速列挙という構文のようです。

高速列挙に関する解説は以下にあります。

CoCoaの素、Objective-Cを知ろう
(第5回 配列とループ処理を理解しよう)
http://www.atmarkit.co.jp/fcoding/articles/objc/05/objc05a.html


Objective-Cでは、C言語のいわゆる通常のforループのほかに、よりオブジェクティブに集合のループ処理を表現するために「列挙子(NSEnumerator)」という仕組みが用意されているそうです。

これを使った場合はコードがやや複雑となるため、高速列挙ということで、for文の構造として表記可能としたようです。

対象となるオブジェクトは、NSArray, NSDictionary,NSSet,NSHashTable, NSMapTable等のNSFastEnumerationプロトコルに準拠するオブジェクトだそうです。

ちなみに、高速列挙ではオブジェクトの変更はできず、変更すると例外が発生するそうです。



構文は次のように定義されています。

for ( Type newVariable in expression ) { stmts }
または
Type existingItem;
for ( existingItem in expression ) { stmts }




以下Appleの解説です。


Objective-C には、コレクションの内容を列挙できる言語機能が提供されています。構文は次のように定義されています。

for ( Type newVariable in expression ) { stmts }
または
Type existingItem;
for ( existingItem in expression ) { stmts }

どちらの場合も、expressionNSFastEnumerationプロトコルに準拠したオブジェクト、すなわち通常は配列または列挙子を生成します(CocoaコレクションクラスのNSArrayNSDictionaryNSSetはこのプロトコルを採用し、NSEnumeratorも同様に採用しています)。

他のオブジェクトのコレクションにアクセスできるインスタンスを持つクラスはすべて、NSFastEnumerationプロトコルを採用できます(NSFastEnumerationプロトコルの実装を参照)。

NSArrayNSSetの場合は、列挙は自身の内容が対象であることは明白です。

それ以外のクラスは、反復処理の対象のプロパティを明確にする必要があります。たとえばNSDictionary、およびCore DataクラスのNSManagedObjectModelは高速列挙に対応しており、NSDictionaryはそのキーを、NSManagedObjectModelはそのエンティティを列挙します。

高速列挙を使用する利点は次のようにいくつかあります。

NSEnumeratorを直接使うなどの手法よりもはるかに効率がよい。
構文が簡単である。
「安全」である。列挙子には変更防止の機能があるため、列挙中にコレクションを変更しようとすると例外が発生します。
反復中のオブジェクトの変更が禁止されているため、複数の列挙を同時に実行できます。

0 件のコメント:

コメントを投稿