Подтвердить что ты не робот

Различия NSMapTable и NSMutableDictionary

Является ли NSMapTable тем же, что и NSMutableDictionary, за исключением того, что ключи являются указателями?

Различается ли управление памятью?

4b9b3361

Ответ 1

Основное различие между NSMapTable и NSMutableDictionary заключается в том, что NSMapTable хранит слабые указатели. Это означает, что когда вы вызываете smth следующим образом:

[my_table setValue: val forKey: key];

значение и ключ не сохраняются (это означает, что им не отправляется сообщение сохранения). Вот почему вы можете использовать любой объект (или, может быть, не объект, но любой указатель), потому что им не нужно отвечать на сохранение сообщения.

Итак, вы, вероятно, захотите использовать NSMapTable, если вы используете сбор мусора, где вам не нужно беспокоиться о том, чтобы сохранить количество объектов.

Ответ 2

NSMapTable более гибкий, чем NSDictionary. В то время как NSDictionary сохраняет сильные ссылки на значения и копирует ключи, вы можете настроить NSMapTable на любое из этих действий независимо для объектов и значений: сильное, слабое или копирование (существуют другие варианты поведения).


Практический пример использования: NSDictionary сохраняет сильную ссылку (сохраняет) указателя значения, но копирует ключ. Это означает, что a) экземпляр ключа должен реализовать протокол NSCopying и b) в зависимости от сложности класса, копирование может добавить накладные расходы. С другой стороны, вы можете настроить NSMapTable, чтобы действовать как NSDictionary, который использует сильные ссылки как для значений, так и для ключей, нет необходимости в копировании или протоколе NSCopying.

Поведение объекта к объекту может быть предварительно эмулировано с использованием NSDictionary, если все ключи были NSNumbers, содержащие память адрес исходного объекта в сопоставлении (не смейтесь, я видел его сделано), но за пределами этого обхода NSMapTable предлагает правду отображение объекта-объекта в первый раз в коллекции Cocoaкласс.

(Из отличная статья, охватывающая NSMapTable, когда она была представлена ​​.)

Посмотрите на API. Это вернет объект, который работает так же, как NSMutableDictionary:

[NSMapTable mapTableWithKeyOptions:NSMapTableCopyIn
                      valueOptions:NSMapTableStrongMemory]

Это вернет объект, который работает, не копирует ключи:

[NSMapTable mapTableWithKeyOptions:NSMapTableStrongMemory
                      valueOptions:NSMapTableStrongMemory]

Примечание. Похоже, что API NSMapTable изменился в последних SDK, но этот синтаксис, похоже, совместим со всеми SDK.

NSMapTable доступен в OS X 10.5+ и iOS 6.0 +.

Ответ 3

Более или менее, у него есть некоторые дополнительные опции, которые в первую очередь актуальны, если вы используете сборку мусора (что, на мой взгляд, довольно устарело). Если вы не используете Garbage Collection, требования к управлению памятью будут одинаковыми.

Другое отличие состоит в том, что NSMapTable может необязательно использовать равенство указателя для хэширования.

Ответ 4

Помните, что NSMapTable иногда не освобождает ключи и объекты, если используются слабые, слабые или сильные слабые привязки http://cocoamine.net/blog/2013/12/13/nsmaptable-and-zeroing-weak-references/.

Также в NSMapTable.h вы можете обнаружить, что записи 'не обязательно очищаются сразу же после того, как слабый ключ исправлен:

+ (id)weakToStrongObjectsMapTable NS_AVAILABLE(10_8, 6_0); 
// entries are not necessarily purged right away when the weak key is reclaimed
+ (id)weakToWeakObjectsMapTable NS_AVAILABLE(10_8, 6_0); 
// entries are not necessarily purged right away when the weak key or object is reclaimed