setObject: forKey: of NSMutableDictionary перезаписывает все данные в словаре - PullRequest
2 голосов
/ 25 января 2012
for ( int cnt = 0 ; cnt < nPeople ; cnt++ )
{
    ABRecordRef ref = CFArrayGetValueAtIndex(allPeople, cnt);

    NSString    *firstName  = (NSString *)ABRecordCopyValue(ref, kABPersonFirstNameProperty);
    NSString    *lastName   = (NSString *)ABRecordCopyValue(ref, kABPersonLastNameProperty);
    NSString    *fullName;   

    /* skipped code at here : code to merge firstName and lastName to fullName. In my country, many of us don't separate first name and last name */

    // tempKeyString : NSString variable that has key of fullNameArray value for nameDictionary.
    // fullNameArray : to keep some fullName variables for tempKeyString.
    if (!tempKeyString) // there's no tempKeyString, a.k.a. it's the first fullName.
    {
        // it's not important to know about GetUTF8String:fullName. It's for my own language.
        tempKeyString = [self GetUTF8String:fullName];
        [fullNameArray addObject:fullName];
    }
    else
    {
        if ([tempKeyString characterAtIndex:0] == [[self GetUTF8String:fullName] characterAtIndex:0]) // if fullName has the same tempKey with fullNameArray.
        {
            [fullNameArray addObject:fullName];
        }
        else // if fullName has different tempKey with fullNameArray.
        {
            //tempKey : key data for fullNameArray
            NSString    *tempKey    = [tempKeyString substringToIndex:1];
            // tempDict : to keep the deep copy of nameDictionary before adding new key.
            NSDictionary *tempDict   = [nameDictionary mutableDeepCopy];
            // add new key (tempKey) with new value (fullNameArray)
            // PROBLEM : ALL values (including previous values) in dictionary(nameDictionary) are overwritten to a new value(fullNameArray).
            [nameDictionary setObject:fullNameArray forKey:tempKey];

            //empties fullNameArray so that it can get the new fullName of the new tempKey.
            [fullNameArray removeAllObjects];
            //refresh tempKeyString, and add the new fullName.
            tempKeyString = [self GetUTF8String:fullName];
            [fullNameArray addObject:fullName];
            ...
        }
    }
}

Я пытаюсь создать объект NSMutableDictionary из контактов моего iPhone.Почему я создаю типизированный объект NSMutableDictionary, потому что мне нужны индексы для контактов, и нелегко напрямую создавать индексы из типизированного объекта ABAddressRef.Мне также нужно сделать функцию поиска ..

Когда я только что написал код, проблем не было, но после отладки единственная проблема сводит меня с ума.После того, как я применил массив с именем fullNameArray с ключом с именем tempKey к namedDictionary, я могу найти, что nameDictionary имеет все значения с ними из fullNameArray. Все предыдущие данные были перезаписаны! Я пытался сделать глубоко скопированную версию предыдущего nameDictionary перед применением fullNameArray и скопировать его в более новый nameDictionary.Однако, когда я проверил точку останова в третьей строке, я не могу найти предыдущие данные в tempDict.

Я добавил больше кодов и комментариев.Это может помочь больше, чем мое объяснение ... любые вопросы рады!

Я пытался найти причину отсюда - StackOverflow - и другие веб-страницы всю ночь, но я не мог найти подобных проблем ..Помогите мне, пожалуйста!Заранее большое спасибо !!

1 Ответ

2 голосов
/ 25 января 2012

Причина, по которой он очищается, заключается в том, что

[nameDictionary setObject:fullNameArray forKey:tempKey];

здесь, вы настраиваете свой словарь с объектом "fullNameArray", затем

[fullNameArray removeAllObjects];

удаляет все значения внутри этогомассив, фактически удаляя ваш объект в «nameDictionary», это один и тот же объект, это не глубокая копия fullNameArray, которую вы храните внутри своего словаря.Зачем вам вообще нужно что-то хранить в массиве?Вы храните только 1 значение.

[nameDictionary setObject:fullName forKey:tempKey];

будет делать то, что вам нужно.Извините, если я ошибаюсь в вашем вопросе, это довольно сложно понять

...