Search code examples
iosobjective-ccocoaios7ios6

NSHashTable with weak references


I want to to use a NSHashTable for keeping weak references to the contained objects. Regarding other customizable behaviors(including equality check), I want the exact same behavior as NSSet(so practically I want to have a NSSet with weak references). Can you give me an example on how to initialize such a hash table?

Would following suffice: [NSHashTable hashTableWithOptions:NSPointerFunctionsWeakMemory]

Also will NSHashTable with weak references automatically remove de-allocated objects?


Solution

  • Yes, you can use NSPointerFunctionsWeakMemory. Facebook KVOController also use NSHashTable with that option, see KVOController

    - (instancetype)init
    {
      self = [super init];
      if (nil != self) {
        NSHashTable *infos = [NSHashTable alloc];
    #ifdef __IPHONE_OS_VERSION_MIN_REQUIRED
        _infos = [infos initWithOptions:NSPointerFunctionsWeakMemory|NSPointerFunctionsObjectPointerPersonality capacity:0];
    #elif defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
        if ([NSHashTable respondsToSelector:@selector(weakObjectsHashTable)]) {
          _infos = [infos initWithOptions:NSPointerFunctionsWeakMemory|NSPointerFunctionsObjectPointerPersonality capacity:0];
        } else {
          // silence deprecated warnings
    #pragma clang diagnostic push
    #pragma clang diagnostic ignored "-Wdeprecated-declarations"
          _infos = [infos initWithOptions:NSPointerFunctionsZeroingWeakMemory|NSPointerFunctionsObjectPointerPersonality capacity:0];
    #pragma clang diagnostic pop
        }
    
    #endif
        _lock = OS_SPINLOCK_INIT;
      }
      return self;
    }
    

    Also, for more convenient way, you can use weakObjectsHashTable

    Returns a new hash table for storing weak references to its contents.

    Return Value A new hash table that uses the options NSHashTableZeroingWeakMemory and NSPointerFunctionsObjectPersonality and has an initial capacity of 0.

    The document is a little bit old, but it is true. See NSHipster NSHash​Table & NSMap​Table

    NSHashTableZeroingWeakMemory: This option has been deprecated. Instead use the NSHashTableWeakMemory option
    

    Note also that

    NSHashTableWeakMemory Equal to NSPointerFunctionsWeakMemory