Вставить объект в NSMutableArray, сохраненный с помощью NSUserDefaults
У меня есть 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:]: метод мутирования, отправленный в неизменяемый объект
почему?
и почему только второй раз?
В первый раз отлично работает!
Ответы
Ответ 1
NSUserDefaults
всегда возвращает неизменяемые объекты, даже если исходный объект изменен. Это в документации для objectForKey
:
Возвращаемый объект является неизменным, даже если значение, которое вы изначально установили, изменено.
Вам нужно будет создать копию возвращаемого объекта, прежде чем изменять его, используя [NSMutableArray arrayWithArray:]
Вероятно, лучше всего использовать метод arrayForKey
NSUserDefaults
, если вы извлекаете массив. Документы здесь: https://developer.apple.com/documentation/foundation/userdefaults
Ответ 2
Вот полный рабочий пример:
- (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];
}
Сначала мы читаем сохраненные данные в изменяемом массиве, обновляем массив, сохраняем новый массив и затем синхронизируем пользовательские значения по умолчанию, чтобы постоянно записывать изменения.
Надеюсь, это поможет!
Ответ 3
Другой вариант:
[[NSUserDefaults standardUserDefaults] setObject:[[[NSUserDefaults standardUserDefaults] objectForKey:@"12345"] arrayByAddingObject:object] forKey:@"12345"];
Ответ 4
Копировать массив из NSUserDefault
следующим образом:
[YourArray addObjectsFromArray:[[NSUserDefaults standardUserDefaults]
objectForKey:@"NSUSD"]];
или
YourArray = [[NSMutableArray alloc]
initWithArray:[[NSUserDefaults standardUserDefaults]
objectForKey:@"NSUSD"]];
[YourArray addObject: (currentObject)];
Ответ 5
Это связано с тем, что вы 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];
Ответ 6
Быстрое исправление:
_retrivedArray = [_mutableArray mutableCopy];