4

나는 다음과 같이 행사라는 사용자 지정 개체가 정의되어 : NSMutableArray를 NSUserDefaults에 저장하는 가장 좋은 방법은 무엇입니까?

#import <Foundation/Foundation.h> 


@interface Occasion : NSObject { 

NSString *_title; 
NSDate *_date; 
NSString *_imagePath;  

} 

@property (nonatomic, retain) NSString *title; 
@property (nonatomic, retain) NSDate *date; 
@property (nonatomic, retain) NSString *imagePath; 

지금 내가 NSUserDefaults에 저장할 행사의있는 NSMutableArray 있습니다. 내가 그것을 할 수있는 가장 쉬운 방법은 궁금 해서요 그래서 똑바로 앞으로 패션에서 가능하지 않다는 거 알아? 직렬화가 대답이라면 어떻게 될까요? 왜냐하면 나는 문서를 읽었으나 문서가 완전히 작동하는 방식을 이해할 수 없었기 때문입니다.

답변

11

나중에 직렬화하는 NSKeyedUnarchiver를 사용하여 다음에, NSData에 배열을 직렬화 NSKeyedArchiver 같은 것을 사용하는 NSUserDefaults에 저장한다 : 당신은 당신의 OccasionNSCoding 프로토콜을 구현해야합니다

NSData *serialized = [NSKeyedArchiver archivedDataWithRootObject:myArray]; 
[[NSUserDefaults standardUserDefaults] setObject:serialized forKey:@"myKey"]; 

//... 

NSData *serialized = [[NSUserDefaults standardUserDefaults] objectForKey:@"myKey"]; 
NSArray *myArray = [NSKeyedUnarchiver unarchiveObjectWithData:serialized]; 

을 클래스를 만들고 올바르게 작동하도록 다양한 속성을 올바르게 저장하십시오. 자세한 내용은 Archives and Serializations Programming Guide을 참조하십시오. 이렇게하려면 몇 줄의 코드 만 있으면 안됩니다. 당신은 OccasionNSCoding을 구현할 수

- (void)encodeWithCoder:(NSCoder *)coder { 
    [super encodeWithCoder:coder]; 

    [coder encodeObject:_title forKey:@"_title"]; 
    [coder encodeObject:_date forKey:@"_date"]; 
    [coder encodeObject:_imagePath forKey:@"_imagePath"]; 
} 

- (id)initWithCoder:(NSCoder *)coder { 
    self = [super initWithCoder:coder]; 

    _title = [[coder decodeObjectForKey:@"_title"] retain]; 
    _date = [[coder decodeObjectForKey:@"_date"] retain]; 
    _imagePath = [[coder decodeObjectForKey:@"_imagePath"] retain]; 

    return self; 
} 
+0

도움 주셔서 감사합니다. 그 아이디어는 나에게 분명합니다. 하나의 마지막 질문 : 단계 (NSArray * myArray = [NSKeyedUnarchiver unarchiveObjectWithData : serialized];)는 원래 배열이 NSMutableArray 인 동안 나에게 NSArray를 제공합니다. 그렇다면 [사본 변경 가능]과 같은 것을 사용해야합니까? – Ali

+0

표준'NSArray'를 돌려 주면'[array mutableCopy]'를 사용하여 변경 가능한 버전을 얻습니다. –

+0

다시 도움을 주셔서 감사합니다. – Ali

1

:처럼 뭔가.

그런 다음 [NSKeyedArchiver archivedDataWithRootObject:myArray]을 사용하여 배열에서 NSData 개체를 만듭니다. 이것을 사용자 기본값으로 넣을 수 있습니다.

3

NSUserDefaults은 응용 프로그램 데이터를 저장하지 않고 사용자 기본 설정을위한 것입니다. CoreData을 사용하거나 오브젝트를 문서 디렉토리에 직렬화하십시오. 클래스가 작동하려면 NSCoding 프로토콜을 구현해야합니다.

1)) Occasion.h

@interface Occasion : NSObject <NSCoding> 

2 NSCoding을 구현 Occasion.m

- (id)initWithCoder:(NSCoder *)aDecoder { 

    if (self = [super init]) { 

     self.title = [aDecoder decodeObjectForKey:@"title"]; 
     self.date = [aDecoder decodeObjectForKey:@"date"]; 
     self.imagePath = [aDecoder decodeObjectForKey:@"imagePath"]; 

    }    
    return self; 
} 

- (void)encodeWithCoder:(NSCoder *)aCoder { 

    [aCoder encodeObject:title forKey:@"title"]; 
    [aCoder encodeObject:date forKey:@"date"]; 
    [aCoder encodeObject:imagePath forKey:@"imagePath"]; 
} 

3 프로토콜을 구현) 문서 디렉토리에있는 파일에 데이터를 보관

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, 
            NSUserDomainMask, YES); 
NSString *documentsPath = [paths objectAtIndex:0]; 
NSString *path= [documentsPath stringByAppendingPathComponent:@“occasions”]; 
[NSKeyedArchiver archiveRootObject:occasions toFile:path]; 

4) 보관 취소하려면 ...

+0

답장을 보내 주셔서 감사합니다. 내 다른 질문은 : 나는 이미 사건 개체에 두 가지 방법을 : (- (id) init 및 - (id) initWithTitle : (NSString *) 제목 날짜 : (NSDate *) 날짜 imagePath : (NSString *) imagePath) 이제는이 두 메서드를 취소하고, Occasion의 새 인스턴스를 만들 때마다 대신 initWithCoder 및 encodeWithCoder를 사용해야합니까? – Ali

+0

아니요. 객체를 만들 때 init 또는 initWithTitle : date : imagePath를 계속 사용하십시오. 코더 메소드는 직렬화에만 사용됩니다. –

+0

알겠습니다. 다시 한번 감사드립니다. – Ali