Использование CFEqual с CFArray и CFDictionary - PullRequest
0 голосов
/ 16 февраля 2011

У меня есть NSArray, который содержит NSDictionaries. Мне нужно преобразовать его в CFMutableArray, который содержит элементы типа CFMutableDictionary с ключами и значениями char *.

- (CFArrayRef)cStringDataSet {
CFArrayCallBacks cfTypeCallBacks = {0, NULL, NULL, NULL, CFEqual};
CFMutableArrayRef cStrDataSet = CFArrayCreateMutable(NULL, 0, &cfTypeCallBacks);

CFDictionaryKeyCallBacks charKeyCallBacks = {0, NULL, NULL, NULL, charEqual, charHash};
CFDictionaryValueCallBacks charValueCallBacks = {0, NULL, NULL, NULL, charEqual};

for (NSDictionary *dict in dataSet) {
    CFMutableDictionaryRef cStrDict = CFDictionaryCreateMutable(NULL, 0, &charKeyCallBacks, &charValueCallBacks);

    for (NSString *key in [dict allKeys]) {
        const char *cStrKey = [key UTF8String];
        const char *cStrValue = [[[dict objectForKey:key] description] UTF8String];

        CFDictionaryAddValue(cStrDict, cStrKey, cStrValue);
    }

    CFArrayAppendValue(cStrDataSet, cStrDict);
}

return cStrDataSet;
}

charEqual и charHash определяются следующим образом:

Boolean charEqual(const void *ptr1, const void *ptr2) {
char *char1 = (char*)ptr1;
char *char2 = (char*)ptr2;

if (strlen(char1) != strlen(char2)) {
    return false;
}

return !strncmp(char1, char2, strlen(char1));
}

CFHashCode charHash(const void *ptr) {
    return (CFHashCode)((int)ptr);
}

Теперь я хочу сравнить два CFArrayRef с использованием CFEqual, но функция charEqual никогда не вызывается, а CFEqual всегда возвращает "false".

1 Ответ

1 голос
/ 16 февраля 2011

Вы нарушаете ограничения на равенство и хэш-коды. Если две строки сравниваются одинаково, то они также должны иметь одинаковый хеш-код. Если словарь реализован с использованием сегментов, он сначала вычислит хеш-код, и только если он найдет совпадение для этого хеш-кода, он вызовет функцию сравнения.

Необходимо убедиться, что charEqual(char1, char2) истинно , только если charHash(char1) == charHash(char2), что означает, что вам нужно переопределить charHash на основе значения строки, а не ее адреса.

...