14

私は KVC を使用して をシリアル化し、NSObjectそれを に保存しようとしています。NSUserDefaultsAttempt to insert non-property valueNSDictionary

問題のオブジェクト のプロパティは次のMyClassとおりです。

@interface MyClass : NSObject
@property (copy,nonatomic) NSNumber* value1;
@property (copy,nonatomic) NSNumber* value2;
@property (copy,nonatomic) NSString* value3;
@property (copy,nonatomic) NSString* value4;
@property (copy,nonatomic) NSString* value5;
@property (copy,nonatomic) NSString* value6;
@property (copy,nonatomic) NSString* value7;
@property (copy,nonatomic) NSString* value8;
@end

MyClass を保存するときは、次の場所で行われます。

-(void)saveMyClass
{
  NSArray* keys = [NSArray arrayWithObjects:
                @"value1",
                @"value2",
                @"value3",
                @"value4",
                @"value5",
                @"value6",
                @"value7",
                @"value8",
                nil];
  NSDictionary* dict = [self dictionaryWithValuesForKeys:keys];
  for( id key in [dict allKeys] )
  {
    NSLog(@"%@ %@",[key class],[[dict objectForKey:key] class]);
  }
  NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
  [defaults setObject:dict forKey:[NSString stringWithString:kMyClassKey]];
  [defaults synchronize];
}

次の出力が生成されます。

2012-02-23 19:35:27.518 MyApp[10230:40b] __NSCFConstantString __NSCFNumber
2012-02-23 19:35:27.519 MyApp[10230:40b] __NSCFConstantString __NSCFNumber
2012-02-23 19:35:27.519 MyApp[10230:40b] __NSCFConstantString __NSCFString
2012-02-23 19:35:27.519 MyApp[10230:40b] __NSCFConstantString __NSCFString
2012-02-23 19:35:27.520 MyApp[10230:40b] __NSCFConstantString __NSCFString
2012-02-23 19:35:27.520 MyApp[10230:40b] __NSCFConstantString __NSCFString
2012-02-23 19:35:27.520 MyApp[10230:40b] __NSCFConstantString __NSCFString
2012-02-23 19:35:27.520 MyApp[10230:40b] __NSCFConstantString NSNull
2012-02-23 18:38:48.489 MyApp[9709:40b] *** -[NSUserDefaults setObject:forKey:]: Attempt to insert non-property value '{
    value1 = "http://www.google.com";
    value2 = "MyClassData";
    value3 = 8;
    value4 = "<null>";
    value5 = "http://www.google.com";
    value6 = 1;
    value7 = "http://www.google.com";
    value8 = 4SY8KcTSGeKuKs7s;
}' of class '__NSCFDictionary'.  Note that dictionaries and arrays in property lists must also contain only property values.`

ご覧のとおり、 内のすべてのオブジェクトdictはプロパティ リストの値であり、そのすべてのキーはNSString*です。これを実行するために欠けているトリビアは何ですか? または、あきらめて使用する必要がありますwriteToFileか?

4

3 に答える 3

21

値を出力することを提案した Kevin に感謝します。もちろん、そのうちの 1 つはNSNullプロパティ リストの値ではないタイプです。ありがとう!

私の問題に対する厄介な解決策 - 私が作成したばかりの辞書のキーを繰り返し処理し、 type のキーをdictionaryWithValuesForKeys削除しNSNullます。はぁ

NSMutableDictionary* dict = [NSMutableDictionary dictionaryWithDictionary:[self dictionaryWithValuesForKeys:keys]];
for( id key in [dict allKeys] )
{
    if( [[dict valueForKey:key] isKindOfClass:[NSNull class]] )
    {
        // doesn't work - values that are entered will never be removed from NSUserDefaults
        //[dict removeObjectForKey:key];
        [dict setObject@"" forKey:key];
    }
}
于 2012-02-24T02:36:39.350 に答える
-2

保管する必要がある場合。

  • カスタム オブジェクトからのデータ、
  • またはカスタム オブジェクトの配列

NSKeyedArchiver メソッドを使用できます。このメソッドに対するリヴァイアサンの回答を確認できます。


ただし、保存しようとしている場合は、

  • NSString または NSNumber のいずれかを含む辞書 (JSON サービス応答から変換された辞書など)、
  • またはこの種の辞書の配列

NSKeyedArchiver を使用する必要はありません。ユーザーのデフォルトを使用できます。


私の場合、ユーザーの既定値から辞書を取得すると、nil が返されたので、NSUserDefaults が辞書を保存したくないと考えました。

ただし、保存されましたが、間違った getter メソッドを使用してユーザーのデフォルトから取得していました。

[[NSUserDefaults standardUserDefaults] stringForKey:<my_key>]

どちらかを使用したことを確認してください。

[[NSUserDefaults standardUserDefaults] dictionaryForKey:<my_key>]

また;

[[NSUserDefaults standardUserDefaults] objectForKey:<my_key>]

他の考えられる理由を確認する前に。

于 2015-03-16T18:01:53.437 に答える