2010-01-28 4 views
1

Я использую NSDictionary как связанный массив (то есть, ключи, которые я использую, могут быть любыми произвольными объектами). Одной из очень неприятных вещей в NSDictionary является то, что он всегда делает копию ключа и сохраняет его. В моем сценарии я позже извлечу ключи из NSDictionary и сделаю некоторые операции с ними. Операция зависит от идентификатора объекта ключей. Поскольку ключи, которые я получил позже, являются копиями объектов, которые я первоначально использовал в качестве ключей. Более поздняя проверка идентификатора объекта не выполняется.NSDictionary, который не копирует ключи для iPhone 3.0 SDK?

Мой вопрос в том, есть ли какая-либо хэш-табличная структура данных в iPhone 3.0 SDK, которая не делает копию ключей? Спасибо.

Outdateboy

ответ

2

Если вы не хотите, чтобы ваш ключ должен быть скопирован (или даже сохранены), вы можете использовать CFDictionary и поставляем kCFTypeDictionaryKeyCallbacks или NULL заказной или ключевые функции обратного вызова.

Для проверки того, соответствуют ли объекты, вы должны использовать -isEqual: вместо ==.

+0

И если вы сравниваете объекты вашего собственного класса, вы просто реализуйте свой собственный метод -isEqual в классе. –

+0

Зачем использовать обратные вызовы 'NULL'? Просто используйте 'kCFTypeDictionaryKeyCallBacks' (сохранить ключи) вместо' kCFCopyStringDictionaryKeyCallBacks' (копировать ключи). –

+0

@Peter: 'kCFCopyStringDictionaryKeyCallBacks' вообще не используется в' NSDictionary', поэтому я думаю, что проблема афера не просто копирование. – kennytm

1

NSDictionary является бесплатным мостом с CFDictionary. Так что просто:

CFDictionarySetValue((CFDictionaryRef)myMutableDict, key, object); 

Это только метод Какао, который копирует ключ.

+1

Я не буду полагаться на NSMutableDictionaries-as-CFMutableDictionaries, не используя обратные вызовы в виде копии. В документации явно не указано (насколько я могу найти), что происходит, когда вы это делаете, но, если угодно, я считаю это ошибкой. –

+0

Я думаю, это трудно понять; документы не очень ясны. Я собираюсь сочетать «это всегда было так» и что документы указывают, что все * методы * для размещения объектов в словаре будут копировать ключ. –

1

Я недавно сделал следующее, чтобы получить MutableDictionary, который не копирует его ключи.

-(NSMutableDictionary*)mutableDictionaryWithRetainedKeys { 
    CFMutableDictionaryRef dictionary = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); 
    return CFBridgingRelease(dictionary); 
} 

Если вы ключи не подчиняются NSCopying, и вы хотите, чтобы избежать предупреждений компилятора при установке ключ/значение использования:

CFDictionarySetValue(dictionary, (__bridge const void *)(key), (__bridge const void *)(value)); 
+0

попробуйте это: возьмите «NSMutableDictionary», который возвращается этим методом, выполните «setObject: forKey:» на нем с ключом пользовательского класса и поставьте точку останова на '-copyWithZone:'; вы увидите, что он называется. Теперь сделайте 'setObject: forKey:' на нем ключ ключа пользовательского класса, который не реализует '-copyWithZone:' (игнорировать любые предупреждения); вы увидите, что он выдает исключение. – user102008

+1

Да, ты прав. Благодарю. Вы должны использовать 'CFDictionarySetValue', чтобы избежать вызова' -copyWithZone: '. –