将NSMutableArray的内容写入plist文件

时间:2011-08-19 03:21:30

标签: objective-c cocoa-touch

因此,我的应用中出现了一个大文本字段的页面,用户输入文本并点击保存按钮。命中保存按钮时,在AppDelegate文件中声明的名为savedPosts的NSMutableArray会将文本字段的文本内容保存到此数组中。即使在AppDelegate中声明了实际数组,也会从其他视图控制器调用此保存代码,而不是AppDelegate。我不确定这是不是一个坏主意,但这仍然不是问题。无论如何,我想要它,以便每次用户点击新帖子或现有帖子上的保存按钮时,它会向该数组添加另一个对象并将该同一对象保存到plist。设置整个事情的最佳方法是将文本字段中的帖子保存到数组中,该数组会自动将其保存到plist中。如何在每次将对象添加到数组时将其添加到plist文件中。数组应该在哪里声明和分配?

2 个答案:

答案 0 :(得分:2)

如果你想确保你的帖子总是在你添加一个新帖子的时候写出来的话,我会做一个非常简单的课程来处理整个帖子。您可以使用一些URL初始化该类,然后将旧的持久数据读入数组并实现一些-appendPost:类型的方法,该方法处理添加新帖子并将数据持久保存回URL。然后,应用程序委托可以简单地管理指向适当URL的此类的实例。你可以根据需要使它变得复杂或简单。

下面附有一个非常简单的类实现,它只是你在问题中描述的内容。然而,应该注意的是,代码仅用于参考值,如果数据集变得非常大,显然不会扩展。

这个简单的参考实现需要iOS 4.0+用于GCD调用,并且需要使用LLVM 2.0+编译器为ivars-in-implementation构建。如果您想支持早期版本的iOS,您可以删除GCD并同步其他方式或阻止(不推荐)。如果你想使用GCC-LLVM而不是Clang构建,你可以将ivar decls移动到界面。

// 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 :(得分:1)

只要您的数组内容由plist对象组成,

-[NSArray writeToFile:atomically:];就会为您做到这一点,使用您的应用程序委托作为与整个应用程序共享数据的中心位置也没有错那就是它的用途。此外,如果此数据在您的应用程序执行之间很小且持久,您可能需要考虑通过NSUserDefaults将其保存到用户默认值。