NSInternalInconsistencyException с NSUserDefaults при использовании метода setValue: forPath - PullRequest
0 голосов
/ 23 мая 2011

Мой код выглядит следующим образом:

NSMutableDictionary *configure = [[NSUserDefaults standardUserDefaults] objectForKey:@"configure"];
if (!configure){    
configure = [NSMutableDictionary dictionary];
[configure setValue:[NSMutableDictionary dictionary] forKeyPath:@"select"] ;

[configure setValue:[NSMutableDictionary dictionary] forKeyPath:@"select.around"];
[configure setValue: @"All" forKeyPath:@"select.around.name"];

[[NSUserDefaults standardUserDefaults] setObject:configure forKey:@"configure"];
[[NSUserDefaults standardUserDefaults] synchronize];
    }
NSString *keyPath = @"configure.select.around";
NSMutableDictionary *aroundConfigure = [[[NSUserDefaults standardUserDefaults] valueForKeyPath:keyPath] mutableCopy];
[aroundConfigure setObject:@"" forKey:@"name"];
[[NSUserDefaults standardUserDefaults] setValue:aroundConfigure forKeyPath:keyPath];

Каждый раз происходит сбой с ошибкой:

** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[__NSCFDictionary setObject:forKey:]: mutating method sent to immutable object'
*** Call stack at first throw:
(
    0   CoreFoundation                      0x00daebe9 __exceptionPreprocess + 185
    1   libobjc.A.dylib                     0x00f035c2 objc_exception_throw + 47
    2   CoreFoundation                      0x00d67628 +[NSException raise:format:arguments:] + 136
    3   CoreFoundation                      0x00d6759a +[NSException raise:format:] + 58
    4   CoreFoundation                      0x00dad401 -[__NSCFDictionary setObject:forKey:] + 209
    5   Foundation                          0x0004b34d -[NSObject(NSKeyValueCoding) setValue:forKeyPath:] + 399
    6   Foundation                          0x0004b34d -[NSObject(NSKeyValueCoding) setValue:forKeyPath:] + 399
    7   Untitled                            0x00002429 -[UntitledAppDelegate application:didFinishLaunchingWithOptions:] + 774
    8   UIKit                               0x002b81fa -[UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 1163
    9   UIKit                               0x002ba55e -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 439
    10  UIKit                               0x002c4db2 -[UIApplication handleEvent:withNewEvent:] + 1533
    11  UIKit                               0x002bd202 -[UIApplication sendEvent:] + 71
    12  UIKit                               0x002c2732 _UIApplicationHandleEvent + 7576
    13  GraphicsServices                    0x016e4a36 PurpleEventCallback + 1550
    14  CoreFoundation                      0x00d90064 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 52
    15  CoreFoundation                      0x00cf06f7 __CFRunLoopDoSource1 + 215
    16  CoreFoundation                      0x00ced983 __CFRunLoopRun + 979
    17  CoreFoundation                      0x00ced240 CFRunLoopRunSpecific + 208
    18  CoreFoundation                      0x00ced161 CFRunLoopRunInMode + 97
    19  UIKit                               0x002b9fa8 -[UIApplication _run] + 636
    20  UIKit                               0x002c642e UIApplicationMain + 1160
    21  Untitled                            0x00002100 main + 102
    22  Untitled                            0x00002091 start + 53
)
terminate called after throwing an instance of 'NSException'

Я знаю, что setObject:forKey: следует использовать с изменяемымдиктаторский.Есть ли проблемы с использованием KVO с NSUserDefaults?Кстати, я использую платформу iPhone.

Ответы [ 3 ]

2 голосов
/ 23 мая 2011

Ваш код не делает то, что, по вашему мнению, делает:

NSMutableDictionary *configure = [[NSUserDefaults standardUserDefaults] objectForKey:@"configure"];

Это устанавливает configure в качестве значения вашего стандартного значения по умолчанию для значения ключа configure

configure = [NSMutableDictionary dictionary];

Устанавливает configure в новый пустой словарь, а не в тот, который вы получили по умолчанию для пользователя

[configure setValue:[NSMutableDictionary dictionary] forKeyPath:@"select"] ;

Теперь вы помещаете пустой словарь в качестве значения для ключа select

[configure setValue:[NSMutableDictionary dictionary] forKeyPath:@"select.around"];

Вы добавляете еще один пустой словарь для этого пути ключа

[configure setValue: @"All" forKeyPath:@"select.around.name"];

И вы устанавливаете строковое значение для этого пути ключа

[[NSUserDefaults standardUserDefaults] setObject:configure forKey:@"configure"];

Вытеперь помещаем этот нечетный словарь в NSUserDefaults

[[NSUserDefaults standardUserDefaults] synchronize];

NSString *keyPath = @"configure.select.around";

NSMutableDictionary *aroundConfigure = [[[NSUserDefaults standardUserDefaults] valueForKeyPath:keyPath] mutableCopy];

Это просто пустой изменяемый словарь

[aroundConfigure setObject:@"" forKey:@"name"];

Вы задаете пустую строку для некоторого ключа в этом словаре

[[NSUserDefaults standardUserDefaults] setValue:aroundConfigure forKeyPath:keyPath];

И затем вы устанавливаете этот странный словарь в пользовательские значения по умолчанию.

Что все очень сбивает с толку.

Что вы пытаетесь сделать?

Отредактировано для добавления

Нет смысла предоставлять код, если вы "упростили""если мы не видим, что он должен делать.

Ваше приложение падает, потому что вы пытаетесь изменить пару значений ключа NSDictionary, которая является неизменной вместо NSMutableDictionary.См. Строку 6 вашего следа.

Поскольку вы предоставили «упрощенный» код - я не знаю, где вы это делаете.

0 голосов
/ 19 января 2015

То, как вы использовали NSUserDefaults, неверно, NSUserDefaults возвращает неизменяемый словарь.Это причина этой проблемы.Следовательно, вы должны явно запросить изменяемый объект у NSUserDefaults.Пожалуйста, используйте строку кода ниже.

NSMutableDictionary *configure = [[[NSUserDefaults standardUserDefaults] objectForKey:@"configure"]mutableCopy];

Эта работа со мной.Спасибо Удачи:)

0 голосов
/ 19 декабря 2012

Сегодня я также столкнулся с этой проблемой, потому что я делаю данные в словаре следующим образом

NSMutableDictionary *Dic =[myMutableAry objectAtIndex:0];  

после получения данных, когда я обновляю значение dic, затем получаю сбой

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

Тогда я получил решение послемного исследований, так что просто сделайте одну вещь

NSMutableDictionary *Dic = [NSMutableDictionary dictionaryWithDictionary:[myMutableAry objectAtIndex:0]];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...