5

내가 (응용 프로그램 문서 폴더)를 .plist 파일에 데이터의 무리를 저장하고있어, 그리고이 같은 구조있어 : 난 그냥
NSMutableDictionary *d = [[NSMutableDictionary alloc] initWithContentsOfFile:plistFile] 로를 검색 할 경우다차원 NSMutableArrays를 저장하고 검색하는 가장 좋은 방법은 무엇입니까?

Dictionary { 
    "description" = "String Value", 
    "sections" = Array (
     Array (
      Number, 
      ... 
      Number 
     ), 
     Array (
      Number, 
      ... 
      Number 
     ) 
    ), 
    "items" = Array (
     Array (
      Number, 
      ... 
      Number 
     ), 
     Array (
      Number, 
      ... 
      Number 
     ) 
    ) 
} 

I하지 않습니다 숫자 개체를 바꿀 수 있을까요? 그래서 지금 당장 데이터를 재귀하고 모든 것을 변경 가능한 버전으로 만들면 한 인스턴스에서 작동하지만 지금은 전체가 변경 가능할 때 mutating method sent to immutable object이라고 말하고 있습니다.

더 쉽고/좋은 방법이 있나요? 차이가 있다면 내 데이터는 정수와 부울뿐입니다.

+0

어떤 객체가이 메소드로 전송되는지와 같은 정보를 조금 더주고 새 버전을 구성하는 데 사용하는 코드와 런타임 오류가 생성되는 코드를 게시 할 수 있습니까? –

+0

값을 편집하기 전에 배열의 사본을 변경 가능합니까? – vfn

답변

9

맞춤 클래스 정크라면 NSPropertyListSerialization을 사용해야합니다. 특히 propertyListWithData:options:format:error: 방법을 참조하십시오. 사용 예 :

NSMutableDictionary *d = [NSPropertyListSerialization propertyListWithData:[NSData dataWithContentsOfFile:@"path/to/file"] 
                    options:NSPropertyListMutableContainers 
                    format:NULL 
                    error:NULL]; 

이렇게하면 모든 컨테이너가 변경 가능하지만 리프 노드 (예 : NSStrings)는 불변으로 유지됩니다. 잎을 변경할 수있게하는 옵션도 있습니다.

+0

+1 흥미 롭습니다.Apple의 설명서에 따르면'options' 매개 변수는 읽을 때 사용할 수 없지만 실제로 plist 파일을 쓸 때 사용할 수 있으므로 읽을 때 데이터를 변경할 수 있습니다. http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Classes/NSPropertyListSerialization_Class/Reference/Reference.html –

+0

속성의 OO 혜택을 얻으려면 맞춤 클래스를 계속 주장합니다. 접근자를 캡슐화하고 읽기 및 쓰기 메소드를 캡슐화 할 수 있지만이 기술은 간단한 읽기 - 수정 - 쓰기가 필요한 경우에 확실히 도움이 될 것입니다. 좋은 물건! –

+0

네, 편의를 위해 맞춤 클래스 경로를갔습니다. 그러나 이것은 매우 간단합니다. 의견을 보내 주셔서 감사합니다. – kbanman

8

일반적으로로드 및 저장을 처리 할 하나 이상의 사용자 정의 클래스를 만드는 것이 더 쉽습니다.

MyThing.h

@interface MyThing : NSObject 
{ 
    NSString * description; 
    NSMutableArray * sections; 
    NSMutableArray * items; 
} 
@property (copy) NSString * description; 
@property (readonly) NSMutableArray * sections; 
@property (readonly) NSMutableArray * items; 
- (void)loadFromFile:(NSString *)path; 
- (void)saveToFile:(NSString *)path; 
@end 

MyThing.m

@implementation MyThing 
@synthesize description; 
@synthesize sections 
@synthesize items; 

- (id)init { 
    if ((self = [super init]) == nil) { return nil; } 
    sections = [[NSMutableArray alloc] initWithCapacity:0]; 
    items = [[NSMutableArray alloc] initWithCapacity:0]; 
    return self; 
} 

- (void)dealloc { 
    [items release]; 
    [sections release]; 
} 

- (void)loadFromFile:(NSString *)path { 
    NSDictionary * dict = [NSDictionary dictionaryWithContentsOfFile:path]; 
    [self setDescription:[dict objectForKey:@"description"]]; 
    [sections removeAllObjects]; 
    [sections addObjectsFromArray:[dict objectForKey:@"sections"]]; 
    [items removeAllObjects]; 
    [items addObjectsFromArray:[dict objectForKey:@"items"]]; 
} 

- (void)saveToFile:(NSString *)path { 
    NSDictionary * dict = [NSDictionary dictionaryWithObjectsAndKeys: 
          description, @"description", 
          sections, @"sections", 
          items, @"items", 
          nil]; 
    [dict writeToFile:path atomically:YES]; 
} 

@end; 

을두고 : 이것은 당신이 명시 적으로 mutableArrays로 배열을 변환 할 수 있습니다 완료하면 loadFromFilesaveToFile 메소드에 모든 패키징 및 패키지 해제 코드를 캡슐화 할 수 있습니다. 이 방법의 가장 큰 장점은 메인 프로그램이 훨씬 간단 얻을 수 있다는 것입니다, 그리고 당신이 속성으로 데이터 구조의 요소에 액세스 할 수 있습니다 :

MyThing * thing = [[MyThing alloc] init]; 
[thing loadFromFile:@"..."]; 
... 
thing.description = @"new description"; 
[thing.sections addObject:someObject]; 
[thing.items removeObjectAtIndex:4]; 
... 
[thing saveToFile:@"..."]; 
[thing release]; 
+0

와우, 꽤 철저한 대답입니다. 그건 내 마음을 넘어서지 못한 이유가 너무 이해가됩니다. 감사합니다. – kbanman

1

당신이 원하는 것은 깊은 변경 가능한 복사본입니다. 코코아에는 그것을 할 수있는 방법이 없습니다. 몇 사람이 전에 딥 복사 구현을 작성했습니다 (example).

그러나 Core Foundation에는이 포함되어 있으며 속성 목록 개체의 변경 가능한 복사본을 만들 수 있으며 디스크에서 속성 목록을 변경할 수있는 데이터 형식으로 읽는 기능을 모두 지원합니다. 물론 코어 파운데이션의 속성 목록 유형은 Cocoa와 브리지로 연결되어 있습니다. 즉, NSArray는 CFArray이고 그 반대의 경우도 마찬가지입니다.

관련 문제