вставить объект в NSMutableArray, сохраненный с NSUserDefaults - PullRequest
17 голосов
/ 18 марта 2011

У меня есть NSMutableArray, сохраненный с NSUserDefaults. Этот массив - мои «любимые» элементы, которые пользователь может сохранить, поэтому, когда я хочу добавить один элемент, мне нужно прочитать массив (из NSuserDefault) и сохранить в первой свободной позиции.

Я использую этот метод для добавления значения в NSMutableArray

-(IBAction)save{
   NSMutableArray *abc = [[NSUserDefaults standardUserDefaults] objectForKey:@"12345"];
   int n = [abc count];
   [abc insertObject:@"aaa" atIndex:n];
   NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
   [[NSUserDefaults standardUserDefaults] setObject:abc forKey:@"12345"];
   [defaults synchronize];
   [abc release];
}

в чем дело? Если пользователь вызывает этот метод два раза, во второй раз приложение вылетает с этим журналом:

* Завершение работы приложения из-за необработанного исключения «NSInternalInconsistencyException», причина: '- [__ NSCFArray insertObject: atIndex:]: метод мутации отправлен в неизменяемый объект'

почему? а почему только второй раз? Первый раз отлично работает!

Ответы [ 6 ]

35 голосов
/ 18 марта 2011

NSUserDefaults всегда возвращает неизменные объекты, даже если исходный объект был изменяемым. Это в документации для objectForKey:

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

Вам нужно будет создать копию возвращенного объекта, прежде чем изменять его, используя [NSMutableArray arrayWithArray:]

Вероятно, также лучше использовать метод arrayForKey из NSUserDefaults, если вы получаете массив. Документы здесь: https://developer.apple.com/documentation/foundation/userdefaults

9 голосов
/ 06 декабря 2013

Вот полный рабочий пример:

- (void)saveScore:(NSNumber *)score
{
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSMutableArray *scoreList = [[NSMutableArray alloc] initWithArray: [defaults objectForKey:@"ScoreList"]];
    [scoreList addObject:score];
    [defaults setObject:scoreList forKey:@"ScoreList"];
    [defaults synchronize];
}

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

Надеюсь, это поможет!

1 голос
/ 07 декабря 2012

Копировать массив из NSUserDefault следующим образом:

[YourArray addObjectsFromArray:[[NSUserDefaults standardUserDefaults] 
                  objectForKey:@"NSUSD"]];

или

YourArray = [[NSMutableArray alloc] 
             initWithArray:[[NSUserDefaults standardUserDefaults]  
              objectForKey:@"NSUSD"]];
[YourArray addObject: (currentObject)];
1 голос
/ 18 мая 2012

Другой вариант:

[[NSUserDefaults standardUserDefaults] setObject:[[[NSUserDefaults standardUserDefaults] objectForKey:@"12345"] arrayByAddingObject:object] forKey:@"12345"];
0 голосов
/ 11 марта 2014

Быстрое исправление:

_retrivedArray = [_mutableArray mutableCopy];
0 голосов
/ 18 марта 2011

Это потому, что вы NSMutablepointer указывает на объект NSUserDefault напрямую.Сначала вы должны скопировать объект NSUserDefault в массив, а затем обработать его.

NSMutableArray *arr= [NSMutableArray arrayWithObjects:@"asd",@"dsa",nil];
    [[NSUserDefaults standardUserDefaults] setObject:arr forKey:@"12345"];
NSMutableArray *abc = [NSMutableArray arrayWithArray:[[NSUserDefaults standardUserDefaults] objectForKey:@"12345"]];
//[[NSUserDefaults standardUserDefaults] objectForKey:@"12345"];
    int n = [abc count];
    [abc insertObject:@"aaa" atIndex:n];
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [[NSUserDefaults standardUserDefaults] setObject:abc forKey:@"12345"];
    [defaults synchronize];
    [abc release];
...