-1

私のコードは次のとおりです。

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:変更可能な辞書で使用する必要があることはわかっています。NSUserDefaults で KVO を使用する際に問題はありますか? ちなみにプラットフォームはiPhoneです。

4

3 に答える 3

2

あなたのコードは、あなたが思っていることをしていません:

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];

そして、この奇妙な辞書をユーザーのデフォルトに設定します。

これは非常に紛らわしいです。

あなたがやろうとしていることは何ですか?

編集して追加

コードを「単純化」しただけでは、コードが何をすべきかわかりません。

NSMutableDictionary ではなく不変の NSDictionary のキーと値のペアを変更しようとしているため、アプリがクラッシュしています。トレースの 6 行目を参照してください。

「簡略化された」コードを提供したので、どこでこれを行っているのかわかりません。

于 2011-05-23T16:52:14.863 に答える
0

NSUserDefaults の使用方法が間違っています。NSUserDefaults は可変でない辞書を返します。それがこの問題の原因です。したがって、NSUserDefaults から可変オブジェクトを明示的に要求する必要があります。以下のコード行を使用してください。

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

これは私と一緒に働きます。ありがとうございます。

于 2015-01-19T14:00:02.240 に答える
0

今日もこの問題に直面しました。これは、このような辞書でデータを作成しているためです

NSMutableDictionary *Dic =[myMutableAry objectAtIndex:0];  

dic値を更新しているときにデータを取得した後、クラッシュする

*キャッチされない例外 'NSInternalInconsistencyException' が原因でアプリを終了します。理由: '-[__NSCFDictionary setObject:forKey:]: 変更メソッドが不変オブジェクトに送信されました'

それから私は多くの研究の後に解決策を得たので、ただ一つのことをしてください

NSMutableDictionary *Dic = [NSMutableDictionary dictionaryWithDictionary:[myMutableAry objectAtIndex:0]];
于 2012-12-19T12:55:55.907 に答える