Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
NSHashTableとNSMapTable

NSHashTable & NSMapTable - NSHipsterの超意訳。

[iphone] NSHashTableとNSMapTable

[2014-08-26 18:45]

NSSetは値を強参照でもつ。NSDictionaryは値は強参照で、キーはコピーされる。 開発者が弱参照の値を保持したいとか、NSCopyingに適合しないオブジェクトをキーにしたい場合はNSValue +valueWithNonretainedObject:を使う必要があった。

このようなケースにおいて、iOS 6(MacではOS X 10.5)以降だと、NSHashTableNSMapTableを使用できる。

NSHashTable

NSHashTableNSSetの代替であり、以下の特徴がある:

  • NSSet/NSMutableSetは要素を強参照で保持し、ハッシュ算出と等値比較は、要素のhashisEqual:メソッドを呼び出す事で行われる
  • NSHashTableはMutableであり、Immutable版はない
  • NSHashTableは要素を弱参照で保持できる
  • NSHashTableは入力時に要素をコピーできる
  • NSHashTableは任意のポインタを含めることができ、ハッシュ算出と等値比較はそのポインタを使う

使用例

NSHashTable * hashTable = [NSHashTable hashTableWithOptions:NSPointerFunctionsCopyIn];
[hashTable addObject:@"foo"];
[hashTable addObject:@"bar"];
[hashTable addObject:@42];
[hashTable removeObject:@"bar"];
NSLog(@"Members: %@", [hashTable allObjects]);

代表的なオプションを紹介する:

  • NSHashTableStrongMemory これがデフォルトの振る舞いであり、NSSetの要素記憶域と同じである。
  • NSHashTableWeakMemory 読み書きバリアに弱参照を使う。解放されたらオブジェクトへの参照はNULLとなる。
  • NSHashTableCopyIn 入力時に要素の確保とコピーを行う。 NSPointerFunction-acquireFunctionを参照のこと。
  • NSHashTableObjectPointerPersonality ハッシュ値と等値比較にシフトしたポインタを使う。descriptionメソッドで使われる。

NSMapTable

NSMapTableNSDictionaryの代替であり、以下の特徴がある:

  • NSDictionary/NSMutableDictionaryはキーをコピーし、値を強参照で保持する
  • NSMapTableはMutableであり、Immutable版はない
  • NSMapTableはキーと値を弱参照で保持できる
  • NSMapTableは入力時に要素をコピーできる
  • NSMapTableは任意のポインタを含めることができ、ハッシュ算出と等値比較はそのポインタを使う

使用例

id delegate = ...;
NSMapTable * mapTable = [NSMapTable mapTableWithKeyOptions:NSMapTableStrongMemory
                                              valueOptions:NSMapTableWeakMemory];
[mapTable setObject:delegate forKey:@"foo"];
NSLog(@"Keys: %@", [[mapTable keyEnumerator] allObjects]);

オプションは NSHashTableと同じものが用意されている。

  • NSMapTableStrongMemory
  • NSMapTableCopyIn
  • NSMapTableObjectPointerPersonality
  • NSMapTableWeakMemory

サブスクリプション

NSMapTableはサブスクリプションが用意されていない。実装することは可能だろう。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment