Невозможно поместить NSString в NSMutableArray и сохранить его в NSUserDefaults - PullRequest
0 голосов
/ 15 сентября 2010

Я получаю эту ошибку: '- [__ NSCFArray insertObject: atIndex:]: метод мутации отправлен в неизменяемый объект'

В ViewDidLoad я инициализировал мой массив:

id object = [[NSUserDefaults standardUserDefaults] objectForKey:@"array"];

    if (object) 
    {
        locationArray = object;
        NSLog(@"retrieved", object);
    }
    else 
    {
        locationArray = [[NSMutableArray alloc] init];
        NSLog(@"init");
    }

ЗатемЯ пытаюсь добавить данные в locationArray:

            ABMultiValueRef multi = ABRecordCopyValue(person, property);
            NSUserDefaults *locatie = [NSUserDefaults standardUserDefaults];

            // Set up an NSArray and copy the values in.
            NSArray *theArray = [(id)ABMultiValueCopyArrayOfAllValues(multi) autorelease];
            //everything goes fine the first time, but the second time i receive an error after at this code:
            [locationArray addObject:theArray];

            [locatie setObject:locationArray forKey:@"array"];

Каждый раз, когда я выбираю адрес, все в порядке.Но каждый второй раз я получаю эту ошибку.Что я сделал не так?

Ответы [ 3 ]

2 голосов
/ 15 сентября 2010
NSString *fname = (NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty);
NSMutableString *lname = (NSMutableString *)ABRecordCopyValue(person, kABPersonLastNameProperty);

Что заставляет вас думать, что ABRecordCopyValue собирается возвращать изменяемую строку здесь?

Просто сообщаем компилятору, что он вернет изменяемую строку (что все «(NSMutableString *) »не означает, что так и будет.Если в документации адресной книги не указано, что это вернет изменчивую строку, предположите, что это не так, и создайте изменяемую строку самостоятельно.

Говоря о том, что…

NSMutableString *name = [[NSMutableString alloc] init];

Вот строка, к которой вы должны добавить.Вам не нужно, чтобы lname был изменяемым, потому что эта строка является изменяемой.

NSMutableString *space = @" ";
fname = [fname stringByAppendingFormat:space];
fname = [fname stringByAppendingFormat:lname];

Делая это, вы теряете созданную изменяемую строку.Здесь вы создаете две промежуточные неизменяемые строки, не добавляя их к изменяемой строке.

name = fname;

И здесь вы полностью отбрасываете изменяемую строку (и, таким образом, пропускаете ее, поскольку вы никогда не освобождали ее).it), заменив его неизменной строкой, которую вы получили из вашей серии stringByAppendingFormat: сообщений.

Что вам нужно сделать, это отправить изменяемую строку name в сообщение appendFormat:, передавая как первое, так и последнееимя строки.Вам не нужна строка space;Вы можете включить это в строку формата.

См. также NSMutableString docs .

[nameArray addObject:fname];

Ни при каких условиях до этого утвержденияВы создали объект NSMutableArray и сохранили его указатель в переменной nameArray.Во всяком случае, ни в каком коде, который вы показали.

Пока вы не сделаете это, эта переменная содержит nil, указатель на отсутствие объекта.Сообщение addObject: ничего не делает, потому что это то, что сообщения nil делают: ничего.Регистрация массива, которого у вас нет, выдает «(null)», потому что это описание nil.

    if (nameArray == nil) {
        NSLog(@"NO DATA TO RETRIEVE FROM USERDEFAULTS");

Вы не показываете код, который извлекается из пользовательских настроек по умолчанию,Даже если вы это сделаете, он вернет неизменный массив, как сказал Свен;вам придется сделать изменчивую копию.

Это лучшее, что я могу сделать без описания проблемы.Возможно, мы сможем предложить вам больше и лучше предложений, если вы отредактируете свой вопрос, чтобы сообщить нам, что происходит, когда вы запускаете приведенный выше код, а не только то, что не происходит.

2 голосов
/ 16 сентября 2010

Проблема возникает, когда вы получаете locationArray от NSUserDefaults и пытаетесь вставить какой-либо объект ([locationArray addObject:theArray];). Объект, который вы получаете из NSUserDefaults, не является изменяемым, поэтому вы должны создать изменяемую копию:

NSMutableArray* locationArray = [[NSUserDefaults standardUserDefaults] objectForKey:@"array"];

if (locationArray != nil)
    locationArray = [[locationArray mutableCopy] autorelease];
else 
    locationArray = [NSMutableArray array];
0 голосов
/ 15 сентября 2010

И не забудьте проверить, что fname не равно nil, прежде чем добавлять его в массив

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...