NSUserDefaultsがiOSでNSMutableDictionaryを保存できなかったのはなぜですか?
-
19-08-2019 - |
質問
NSMutableDictionary
にNSUserDefaults
オブジェクトを保存したい。 NSString
のキータイプはNSArray
、値タイプはNSCoding
で、<=>を実装するオブジェクトのリストが含まれています。ドキュメントごとに、<=>と<=>は両方とも<=>に準拠しています。
このエラーが発生しています:
[NSUserDefaults setObject:forKey:]:クラスNSCFDictionaryの非プロパティ値を挿入しようとします。
解決
別の方法を見つけました。保存する前に、NSArray
で終わるNSKeyedArchiver
を使用してルートオブジェクト(NSData
オブジェクト)をエンコードします。次に、UserDefaultsを使用してNSKeyedUnarchiver
を保存します。
データが必要になったら、CommentItem
を読み取り、<=>を使用して<=>をオブジェクトに変換します。
<=>に毎回>に変換する必要があるため、少し面倒ですが、動作します。
リクエストごとに1つの例を示します:
保存:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSMutableArray *arr = ... ; // set value
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:arr];
[defaults setObject:data forKey:@"theKey"];
[defaults synchronize];
ロード:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSData *data = [defaults objectForKey:@"theKey"];
NSArray *arr = [NSKeyedUnarchiver unarchiveObjectWithData:data];
配列内の要素は
を実装します@interface CommentItem : NSObject<NSCoding> {
NSString *value;
}
次に、<=>の実装で、2つのメソッドを提供します:
-(void)encodeWithCoder:(NSCoder *)encoder
{
[encoder encodeObject:value forKey:@"Value"];
}
-(id)initWithCoder:(NSCoder *)decoder
{
self.value = [decoder decodeObjectForKey:@"Value"];
return self;
}
誰でもより良い解決策がありますか?
みんなありがとう。
他のヒント
ユーザーのデフォルトでオブジェクトを保存する場合、すべてのオブジェクトは、再帰的に、ずっと下まで、プロパティリストオブジェクトでなければなりません。 NSCodingに準拠しているということは、ここでは何の意味もありません。NSUserDefaults
は自動的にNSData
にエンコードしません。 <!> quot; NSCoding
<!> quotを実装するオブジェクトのリストの場合;プロパティリストオブジェクトではないオブジェクトを意味する場合、ユーザーのデフォルトに保存する前にそれらを使用して処理する必要があります。
FYIプロパティリストクラスは、NSDictionary
、NSArray
、NSString
、NSDate
、NSNumber
、およびNSMutableDictionary
です。可変サブクラス(<=>など)をユーザー設定に書き込むことができますが、読み出すオブジェクトは常に不変です。
すべてのキーは辞書にありますNSString
s?辞書をプロパティリストに保存するには、それらが必要だと思います。
最も簡単な回答:
キーがNSStrings の場合、 NSDictionary
は plistオブジェクトのみです。
したがって、 <!> quot; Key <!> quot; をNSString
とstringWithFormat
で保存します。
解決策:
NSString *key = [NSString stringWithFormat:@"%@",[dictionary valueForKey:@"Key"]];
利点:
- String-Value が追加されます。
- 変数の値が
NULL
の場合、空の値が追加されます。
NSCoding
プロトコルの実装を検討したことがありますか?これにより、<=>で実装される2つの簡単なメソッドを使用して、iPhoneでエンコードとデコードを行うことができます。まず、<=>をクラスに追加する必要があります。
例を次に示します。
これは.hファイルにあります
@interface GameContent : NSObject <NSCoding>
次に、NSCodingプロトコルの2つのメソッドを実装する必要があります。
- (id) initWithCoder: (NSCoder *)coder
{
if (self = [super init])
{
[self setFoundHotSpots:[coder decodeObjectForKey:@"foundHotSpots"]];
}
return self;
}
- (void) encodeWithCoder: (NSCoder *)coder
{
[coder encodeObject:foundHotSpots forKey:@"foundHotSpots"];
}
詳細については、NSCoderのドキュメントを参照してください。これは、アプリケーションが閉じている場合にiPhoneでアプリケーションの状態を保存し、再びオンになったときに元の状態に戻す必要があるプロジェクトで非常に便利です。
重要なのは、インターフェイスにプロトコルを追加し、<=>の一部である2つのメソッドを実装することです。
これが役立つことを願っています!
これ以上の解決策はありません。別のオプションは、コード化されたオブジェクトをディスクに保存することです-しかし、それは同じことをしています。どちらもNSDataになり、NSDataは元に戻すときにデコードされます。