2011-08-19 4 views
0

큰 텍스트 필드가 나타나고 사용자가 텍스트를 입력하고 저장 버튼을 누르는 페이지를 내 앱에서 작성합니다. 저장 버튼을 누르면 AppDelegate 파일에 선언 된 savedPosts라는 NSMutableArray가 텍스트 필드의 텍스트 내용을이 배열에 저장합니다. 이 저장 코드는 AppDelegate에서 실제 배열이 선언 되었더라도 AppDelegate가 아닌 다른보기 컨트롤러에서 호출됩니다. 그게 나쁜 생각인지 잘 모르겠지만 여전히 문제는 아닙니다. 어쨌든, 사용자가 새 게시물이나 기존 게시물의 저장 버튼을 누를 때마다 배열에 다른 객체를 추가하고 동일한 객체를 plist에 저장하기를 원합니다. 이 모든 것을 설정하는 가장 좋은 방법은 텍스트 필드의 게시물을 plist에 자동 저장하는 배열로 저장하는 것입니다. plist 파일을 배열에 추가 할 때마다 개체를 plist 파일에 추가하는 방법은 무엇입니까? 배열을 어디에 선언하고 할당해야합니까?plist 파일에 NSMutableArray의 내용 작성하기

답변

2

새 게시물을 추가 할 때마다 게시물이 항상 작성되도록하려면 게시물을 전체적으로 처리하는 매우 간단한 클래스를 작성해야합니다. 클래스를 초기화하여 기존 영구 데이터를 배열로 읽어 들이고 새로운 게시물을 추가하고 데이터를 URL에 다시 유지하는 방법을 구현하는 -appendPost: 유형의 메소드를 구현할 수 있습니다. 앱 대리자는이 클래스의 인스턴스를 관리하여 해당 URL을 가리 킵니다. 필요한만큼 복잡하거나 간단하게 만들 수 있습니다.

매우 간단한 클래스 구현이 아래에 첨부되어 있습니다.이 클래스는 질문에 설명 된 것과 정확히 일치합니다. 그러나 코드가 참조 용으로 만 사용되고 데이터 세트가 매우 커질 경우 분명히 확장되지 않습니다.

이 간단한 참조 구현에는 GCD 호출에 iOS 4.0 이상이 필요하며 ivars-in-implementation을 위해 LLVM 2.0+ 컴파일러로 빌드해야합니다. 이전 버전의 iOS를 지원하려면 GCD를 제거하고 다른 방법으로 동기화하거나 차단하십시오 (권장하지 않음). Clang 대신 GCC-LLVM을 사용하여 빌드하고 싶다면 ivar을 인터페이스로 이동시킬 수 있습니다.

// Posts.h 
#import <Foundation/Foundation.h> 

@interface Posts : NSObject 

@property(nonatomic, readonly) NSArray* posts; 

// Initialize with array at URL or create file 
// if no array is there; if nil, posts contents 
// are not persisted 
- (id)initWithURL:(NSURL*)url; 
- (void)appendPost:(NSString*)post; 

@end 

// Posts.m 
#import "Posts.h" 

@implementation Posts { 
    // Persistent content URL 
    NSURL* _url; 

    // In-memory array 
    NSMutableArray* _posts; 

    // Used for synchronizing 
    dispatch_queue_t _postQueue; 
} 

@dynamic posts; 

- (id)init 
{ 
    return [self initWithURL:nil]; 
} 

- (id)initWithURL:(NSURL*)url 
{ 
    if((self = [super init])) { 
     if(url) { 
      _url = [url copy]; 
      _posts = [[NSMutableArray alloc] initWithContentsOfURL:_url]; 
      if(!_posts) { 
       // You may not want to do this as it may later destroy whatever may have been at _url 
       NSLog(@"Warning: Could not parse contents of url '%@': Creating new file", _url); 
      } 
     } else { 
      _posts = [[NSMutableArray alloc] init]; 
     } 
     _postQueue = dispatch_queue_create("org.example.post_queue", 0); 
    } 
    return self; 
} 

- (void)dealloc 
{ 
    [_url release]; 
    [_posts release]; 
    dispatch_release(_postQueue); 
    [super dealloc]; 
} 

- (NSArray*)posts 
{ 
    __block NSArray* posts = nil; 
    if(dispatch_get_current_queue() != _postQueue) { 
     dispatch_sync(_postQueue, ^{ posts = [_posts copy]; }); 
    } else { 
     posts = [_posts copy]; 
    } 
    return [posts autorelease]; 
} 

- (void)appendPost:(NSString*)post 
{ 
    if([post length] == 0) return; 

    dispatch_async(_postQueue, ^{ 
     [_posts appendObject:post]; 
     if(_url) [_posts writeToURL:_url atomically:YES]; 
    }); 
} 

@end 
1

-[NSArray writeToFile:atomically:]; 귀하의 배열 내용이 plist 개체로되어있는 한 당신도 할 것이며, 응용 프로그램 위임자를 전체 응용 프로그램과 공유 할 수있는 중심 위치로 사용할 때도 아무런 문제가 없습니다. 그것을 위해. 또한이 데이터가 작고 응용 프로그램 실행간에 지속되는 경우 NSUserDefaults를 통해 사용자 기본값으로 저장하는 것이 좋습니다.

관련 문제