NSDictionary
INDEX>Foundation>NSDictionary
変更しない辞書クラス
編集時のバージョン OS X 10.8/iOS 10.6
解説
「辞書」と呼ばれるコレクションクラスの一つです。
継承 | NSObject |
準拠 | NSCopying |
NSMutableCopying | |
NSFastEnumeration | |
NSSecureCoding | |
NSObject (NSObject) | |
フレームワーク | /System/Library/Frameworks/Foundation.framework |
使用可能 | Mac OS X v10.0 以降 |
iOS 2.0 以降 | |
定義 | NSDictionary.h |
NSFileManager.h | |
NSKeyValueCoding.h |
概要
NSDictionaryクラスは、辞書と呼ばれ、キーと対応する値(オブジェクト)を保持するコレクションオブジェクトです。
他言語でマップまたは連想配列と呼ばれるものです。
作成、初期化すると変更は出来ません。キーはNSDictionaryオブジェクトにコピーされるのでキーの内容を変更することは出来ませんが、値(オブジェクト)はどこにあるかが保持されるだけなのでNSMutableStringなどの変更可能なオブジェクトであれば、値自体の変更は可能です。
似たようなクラスで、キーで対応する値を保持するNSCacheクラスがありますが、こちらはキーがNSCacheオブジェクトに保持されないので、キーの変更が可能です。
NSDictionaryでオブジェクトを検索する際にキーを使うので、キーは同じものがあってはいけません。キーが同じかどうかはisEqual:メッセージが送信されて比較されます。
キーや値がなにもないことを表す場合はNSNullオブジェクトを使用します。
トールフリーブリッジ
NSDictionaryはCore FoundationのCFDictionaryRefとトールフリーブリッジです。
ARC環境の場合は__bridge、__bridge_retainedなどを使って変換しなければなりません。
#pragma mark NSDictionary TOOL FREE BRIDGE: -(void)method004 { //元となるのNSDictionaryを作成 NSDictionary *aDictionary = [NSDictionary dictionaryWithObjectsAndKeys:@"aaa",@"key1",@"bbb",@"key2",@"ccc",@"key3", nil]; NSLog(@"%s aDictionary %p = %@",__FUNCTION__,aDictionary,[aDictionary description]); CFDictionaryRef dict = (__bridge_retained CFDictionaryRef)aDictionary; CFShow(dict); //=><CFBasicHash 0x6c161d0 [0x145eb48]>{type = immutable dict, count = 3, //entries => //0 : <CFString 0x4620 [0x145eb48]>{contents = "key2"} = <CFString 0x4610 [0x145eb48]>{contents = "bbb"} //1 : <CFString 0x4600 [0x145eb48]>{contents = "key1"} = <CFString 0x45f0 [0x145eb48]>{contents = "aaa"} //2 : <CFString 0x4640 [0x145eb48]>{contents = "key3"} = <CFString 0x4630 [0x145eb48]>{contents = "ccc"} //} NSDictionary *newDictionary = (__bridge NSDictionary*)dict; NSLog(@"%s newDictionary %p = %@",__FUNCTION__,newDictionary,[newDictionary description]); //=>-[OOOAppDelegate method004] newDictionary 0x6c161d0 = {key1 = aaa;key2 = bbb;key3 = ccc;} //ポインタの部分は毎回変わります。 }
本クラスについて
キーと値で構成されたペア(エントリーと呼ばれます)を持つ、辞書を呼ばれるクラスです。作成・初期化後は変更することができません。変更可能な辞書はNSMutableDictionaryを使用します。
辞書自体は変更できませんが、含まれる要素が変更可能なオブジェクトの場合(例えばNSMutableString)、そのオブジェクトの内容を変更することはできます。
辞書作成時にキーは辞書内にコピーされ、値は参照のみが保持されます。(一部のメソッドを除く)
C言語のフレームワークである、Core FoundationのCFDictionaryRefとトールフリーブリッジです。ARC環境以外ではそのまま使用できます。
どちらかのフレームワークにしかないメソッド・関数を使いたい場合、キャストして使うことが出来ます。
ARC環境では、管理対象のオブジェクトのキャストに__bridge、__bridge_retained、__bridge_transferが必要になります。
作成
オブジェクトの配列とキーの配列で作成するメソッド(+ dictionaryWithObjects:forKeys、+ dictionaryWithObjects:forKeys:count)、オブジェクト・キーの繰り返し(最後はnil)で作成するメソッド(+ dictionaryWithObjectsAndKeys)があります。
ファイルパスを指定してそのファイルから作成するメソッド(+ dictionaryWithContentsOfFile)、URLを指定してそのファイルから作成するメソッド(+ dictionaryWithContentsOfURL)があります。
初期化
オブジェクトの配列とキーの配列で初期化するメソッド(– initWithObjects:forKeys、– initWithObjects:forKeys:count)、オブジェクト・キーの繰り返し(最後はnil)で作成するメソッド(– initWithObjectsAndKeys)があります。
ファイルパスを指定してそのファイルから初期化するメソッド(– initWithContentsOfFile)、URLを指定してそのファイルから作成するメソッド(– initWithContentsOfURL)があります。
初期化の際、通常キーはコピーされますが、値はコピーされません。値をコピーするオプションを持ったメソッド(– initWithDictionary:copyItems)を使い、copyItems:にYESを渡すことで値となるオブジェクトがコピーされるようになります。
エントリーのカウント
キーと値のペアからなるエントリーの数が辞書にいくつ含まれるかを知るには(– count)メソッドを使います。
辞書の比較
他の辞書を内容が同じかどうかを調べるには(– isEqualToDictionary)メソッドを使います。
他の辞書と同じかどうかの条件は、エントリの数が同数であり、かつ各キーに対して値が同じかどうかisEqual:でテストしてYESの場合に同じ辞書だと判断されます。
キーと値へのアクセス
すべてのキーを配列で返すメソッド(– allKeys)、すべての値を配列で返すメソッド(– allValues)、指定されたオブジェクトに対応するキーを配列で返すメソッド(– allKeysForObject)があります。
指定したキーに対応する値のオブジェクトを返すメソッド(– objectForKey)、複数の値に対応するキーを配列で返すメソッド(– objectsForKeys:notFoundMarker)、キーバリューコーディングで使用するメソッド(– valueForKey)があります。
– objectForKeyと– valueForKeyは、ほぼ同じ値を返すのですが、最初の文字が"@"の場合、– valueForKeyではキーバリューコーディングの演算子として違った挙動をしますので注意が必要です。
辞書からのオブジェクトを取り出しは– objectForKeyを使います。
#pragma mark NSDictionary valueForKey -(void)method018 { NSDictionary *aDictionary = [NSDictionary dictionaryWithObjectsAndKeys:@"aaa",@"key1",@"bbb",@"key2",@"ccc",@"key3", nil]; NSLog(@"%s %p %@",__FUNCTION__,aDictionary,[aDictionary objectForKey:@"@count"]); NSLog(@"%s %p %@",__FUNCTION__,aDictionary,[aDictionary valueForKey:@"@count"]); NSLog(@"%s %p %@",__FUNCTION__,aDictionary,[aDictionary objectForKey:@"@allKeys"]); NSLog(@"%s %p %@",__FUNCTION__,aDictionary,[aDictionary valueForKey:@"@allKeys"]); //=>-[OOOAppDelegate method018] 0x6a62d60 (null) //=>-[OOOAppDelegate method018] 0x6a62d60 3 //=>-[OOOAppDelegate method018] 0x6a62d60 (null) //=>-[OOOAppDelegate method018] 0x6a62d60 (key2,key1,key3) }
辞書の列挙
NSEnumeratorを返すメソッドとして(– keyEnumerator)(– objectEnumerator)がありますが、ブロックオブジェクトを使って列挙を行うメソッド(– enumerateKeysAndObjectsUsingBlock、– enumerateKeysAndObjectsWithOptions:usingBlock)がiOS4.0から利用可能となっています。
#pragma mark NSDictionary enumerateKeysAndObjectsWithOptions:usingBlock: -(void)method020 { NSDictionary *aDictionary = [NSDictionary dictionaryWithObjectsAndKeys:@"aaa",@"key1",@"bbb",@"key2",@"ccc",@"key3", nil]; [aDictionary enumerateKeysAndObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(id key, id obj,BOOL *stop) { NSLog(@"%s %p %@=%@",__FUNCTION__,aDictionary,key,obj); if ([obj isEqualToString:@"ccc"]) { *stop = YES; } }]; //=> 0x6a4f7a0 key2=bbb //=> 0x6a4f7a0 key1=aaa //=> 0x6a4f7a0 key3=ccc }
辞書のソート
辞書をソートするには大きく分けて二つあります。一つはセレクタを使うメソッド(– keysSortedByValueUsingSelector)、もう一つはコンペレーターを使うメソッド(– keysSortedByValueUsingComparator)です。
オブジェクトをソートしてソートされたキーの配列を返します。
#pragma mark sortedArrayWithOptions:usingComparator: -(void)method022 { NSDictionary *aDictionary = [NSDictionary dictionaryWithObjectsAndKeys:@"bbb",@"key2",@"ccc",@"key3",@"aaa",@"key1", nil]; NSArray *sortedKeyArray = [aDictionary keysSortedByValueWithOptions:NSEnumerationConcurrent usingComparator:^(id obj1,id obj2){ return [obj1 compare:obj2]; }]; NSLog(@"%s %p %@",__FUNCTION__,sortedKeyArray,[sortedKeyArray description]); //=>-[OOOAppDelegate method021] 0x6a3a1e0 (key1,key2,key3) }
辞書のフィルタリング
条件に合うエントリのキーをNSSetオブジェクトにして返すメソッド(– keysOfEntriesPassingTest)があります。
NSSetクラスは、順序と重複がないコレクションクラスです。
#pragma mark indexOfObjectPassingTest: -(void)method023 { NSDictionary *aDictionary = [NSDictionary dictionaryWithObjectsAndKeys:@"obj",@"key2",@"obj",@"key3",@"aaa",@"key1", nil]; NSSet *aSet = [aDictionary keysOfEntriesPassingTest:^ BOOL (id key ,id obj, BOOL *stop) { if ([obj isEqualToString:@"obj"]) { return YES; }else { return NO; } }]; NSLog(@"%s %p %@",__FUNCTION__,aSet,[aSet description]); }
辞書の保存
ファイルパスを使用するメソッド(– writeToFile:atomically)とURLを使用するメソッド(– writeToURL:atomically)があります。
atomically:にYESを渡すことで、一旦一時ファイルに書き出してその後リネームする方法で書き出されます。
列挙
Mac OS X 10.5 以降ではNSFastEnumerationプロトコルをサポートします。
Mac OS X 10.6 以降、iOS4.0以降では、NSDictionaryはブロックオブジェクトを使って列挙をサポートします。
辞書の作成
+ dictionary
+ dictionaryWithContentsOfFile
+ dictionaryWithContentsOfURL
+ dictionaryWithDictionary
+ dictionaryWithObject:forKey
+ dictionaryWithObjects:forKeys
+ dictionaryWithObjects:forKeys:count
+ dictionaryWithObjectsAndKeys
インスタンスの作成
– initWithContentsOfFile
– initWithContentsOfURL
– initWithDictionary
– initWithDictionary:copyItems
– initWithObjects:forKeys
– initWithObjects:forKeys:count
– initWithObjectsAndKeys
共有キーセットを作成
要素数
辞書の比較
キーと値のアクセス
– allKeys
– allKeysForObject
– allValues
– getObjects:andKeys
- objectForKeyedSubscript
– objectForKey
– objectsForKeys:notFoundMarker
– valueForKey
辞書の列挙化
– keyEnumerator
– objectEnumerator
– enumerateKeysAndObjectsUsingBlock
– enumerateKeysAndObjectsWithOptions:usingBlock
辞書のソート
– keysSortedByValueUsingSelector
– keysSortedByValueUsingComparator
– keysSortedByValueWithOptions:usingComparator
ファイル属性にアクセス
– fileCreationDate
– fileExtensionHidden
– fileGroupOwnerAccountID
– fileGroupOwnerAccountName
– fileHFSCreatorCode
– fileHFSTypeCode
– fileIsAppendOnly
– fileIsImmutable
– fileModificationDate
– fileOwnerAccountID
– fileOwnerAccountName
– filePosixPermissions
– fileSize
– fileSystemFileNumber
– fileSystemNumber
– fileType