[ios] NSUserDefaults가 iOS에서 NSMutableDictionary를 저장하지 못한 이유는 무엇입니까?

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키가 NSString 인 경우 plist 객체 일뿐 입니다. 그래서, 보관 “키” 로 와를 .NSStringstringWithFormat


해결책 :

NSString *key = [NSString stringWithFormat:@"%@",[dictionary valueForKey:@"Key"]];

혜택 :

  1. String-Value 를 추가 합니다 .
  2. 변수 값이 인 경우 빈 값 을 추가 합니다 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로 끝나고 다시 원할 때 디코딩됩니다.


답변