왜 nsuserDefaults가 iOS에서 nsMutableDictionary를 저장하지 못했습니까?
-
19-08-2019 - |
문제
저를 저장하고 싶습니다 NSMutableDictionary
객체에 NSUserDefaults
. 핵심 유형 NSMutableDictionary
~이다 NSString
, 값 유형은입니다 NSArray
, 여기에는 구현하는 객체 목록이 포함되어 있습니다 NSCoding
. 문서 당, NSString
그리고 NSArray
둘 다 준수합니다 NSCoding
.
이 오류가 발생합니다.
nsuserDefaults setObject : forkey :] : 클래스 nscfdictionary의 비 프로퍼티 값을 삽입하려고 시도합니다.
해결책
하나의 대안을 찾았습니다. 저장하기 전에 루트 객체를 인코딩합니다 (NSArray
개체) 사용 NSKeyedArchiver
, 그것은 끝납니다 NSData
. 그런 다음 userDefaults를 사용하십시오 NSData
.
데이터가 필요할 때 NSData
, 및 사용 NSKeyedUnarchiver
변환하다 NSData
물체로 돌아갑니다.
나는 약간 번거 롭다. NSData
매번 작동하지만 작동합니다.
요청 당 한 예는 다음과 같습니다.
구하다:
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;
}
그런 다음 구현에서 CommentItem
, 두 가지 방법을 제공합니다.
-(void)encodeWithCoder:(NSCoder *)encoder
{
[encoder encodeObject:value forKey:@"Value"];
}
-(id)initWithCoder:(NSCoder *)decoder
{
self.value = [decoder decodeObjectForKey:@"Value"];
return self;
}
누구든지 더 나은 솔루션이 있습니까?
모두 감사합니다.
다른 팁
사용자 기본값에 객체를 저장하는 경우, 모든 객체는 재귀 적으로 모든 객체가 속성 목록 개체 여야합니다. NSCoding을 준수하는 것은 여기서 의미가 없습니다. NSUserDefaults
자동으로 인코딩하지 않습니다 NSData
, 당신은 스스로해야합니다. "구현하는 객체 목록 인 경우 NSCoding
"속성 목록 객체가 아닌 객체를 의미하며, 사용자 기본값에 저장하기 전에 그들과 무언가를해야합니다.
참고로 속성 목록 클래스는입니다 NSDictionary
, NSArray
, NSString
, NSDate
, NSData
, 그리고 NSNumber
. 돌연변이 가능한 서브 클래스를 쓸 수 있습니다 (예 : NSMutableDictionary
) 사용자 환경 설정에 대해서는 읽은 객체는 항상 불변입니다.
사전의 모든 열쇠입니다 NSString
에스? 사전을 속성 목록에 저장하려면 그들이해야한다고 생각합니다.
가장 간단한 답변 :
NSDictionary
단지 a PLIST 대상 , 경우 키는 nsstrings입니다. 그래서 저장하십시오 "열쇠" ~처럼 NSString
~와 함께 stringWithFormat
.
해결책 :
NSString *key = [NSString stringWithFormat:@"%@",[dictionary valueForKey:@"Key"]];
이익 :
- 추가됩니다 문자열 값.
- 추가됩니다 빈 가치 변수 값이있을 때
NULL
.
당신은 그것을 구현하는 것을 고려 했습니까? NSCoding
규약? 이렇게하면 iPhone을 인코딩하고 디코딩 할 수 있습니다. NSCoding
. 먼저 추가해야합니다 NSCoding
수업에.
예는 다음과 같습니다.
이것은 .h 파일에 있습니다
@interface GameContent : NSObject <NSCoding>
그런 다음 NSCoding 프로토콜의 두 가지 방법을 구현해야합니다.
- (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에 응용 프로그램 상태를 저장하고 다시 켜져있을 때 상태로 다시 복원 해야하는 프로젝트에 정말 편리합니다.
열쇠는 인터페이스에 프로토콜을 추가 한 다음의 일부인 두 가지 메소드를 구현하는 것입니다. NSCoding
.
이게 도움이 되길 바란다!
더 나은 솔루션은 없습니다. 또 다른 옵션은 코딩 된 객체를 디스크에 저장하는 것입니다. 그러나 그것은 같은 일을하는 것입니다. 그들은 둘 다 당신이 그것을 원할 때 해독되는 nsdata로 끝납니다.