使用 NSObjects 将文件保存到文档 NSMutableArray 的问题

Posted

技术标签:

【中文标题】使用 NSObjects 将文件保存到文档 NSMutableArray 的问题【英文标题】:Issue with save file to Documents NSMutableArray with NSObjects 【发布时间】:2011-08-12 09:53:26 【问题描述】:

我是一名新手 ios 开发人员。 我编写了一个小应用程序,它保存了一个NSMutableArray 数组,其中包含从NSObject 派生的对象。 应用程序进行保存,但文件未在文档目录中创建,应用程序无法读取。 这个问题在模拟器和我的 iPhone 3gs 4.2.1 上都有

我在appDelegate 类中的NSMutableArray 定义:

@property (nonatomic,retain, readwrite) NSMutableArray *places;

我的 NSObject 类:

 #import <Foundation/Foundation.h>


@interface Place : NSObject 
    NSString *name;
    NSString *location;


-(id) init:(NSString *)name: (NSString *)location;

@property (retain,nonatomic,readwrite) NSString *name;
@property (retain,nonatomic,readwrite) NSString *location;

@end

我的 StorageService 库类:

 #import "StorageService.h"


@implementation StorageService

-(id) init 
    self = [super init];
    if (self != nil) 

    
    return self;



-(void) saveArrayToFile:(NSString*) filename : (NSMutableArray *)arrayToSave
    // get full path
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *fullPath = [paths objectAtIndex:0];
    fullPath = [fullPath stringByAppendingPathComponent:filename];  
    NSLog(@"Save in %@",fullPath);
    [arrayToSave writeToFile:fullPath atomically:YES];


-(NSMutableArray*) readArrayFromFile:(NSString *)filename 
    // get full path
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *fullPath = [paths objectAtIndex:0];
    fullPath = [fullPath stringByAppendingPathComponent:filename];

    if ([[NSFileManager defaultManager] fileExistsAtPath:fullPath]) 
        NSMutableArray *data = [[NSMutableArray alloc] initWithContentsOfFile:fullPath];
        if (data == nil) 
            data = [[NSMutableArray alloc] init];
        
        NSLog(@"Read from %@",fullPath);
        return data;
     else 
        NSMutableArray *data = [[NSMutableArray alloc] initWithContentsOfFile:fullPath];
        return data;
    


-(void) dealloc 
    [super dealloc];


@end

appDelegate中的我的函数:

    -(void) saveApplicationData 
    [self.storageService saveArrayToFile : PLACES_FILE : self.places];


-(void) loadApplicationData 
    self.places = [self.storageService readArrayFromFile:PLACES_FILE];

这是我的类,它对文件名保持不变:

    #import <Foundation/Foundation.h>

extern NSString * const PLACES_FILE = @"Places.dat";

@interface ApplicationConstants : NSObject 



@end

那么有什么问题呢?

谢谢你们。

【问题讨论】:

【参考方案1】:

您想要的是让Place 符合NSCoding 协议,以允许对文件进行序列化(如果需要,还可以在内存数据中)

Place 扩展为 (我还更改了 init 方法的名称,因为您的名字违反了 iOS 的所有命名惯例)

@interface Place : NSObject <NSCoding> 
    NSString *name; 
    NSString *location; 


-(id)initWithName:(NSString *)name location:(NSString *)location;

@property (retain,nonatomic,readwrite) NSString *name; 
@property (retain,nonatomic,readwrite) NSString *location;

@end

您的实现非常简单,但您还需要实现NSCoding 协议定义的两个方法:

@implementation Place

@synthesize name, location;

-(id)initWithName:(NSString *)aName location:(NSString *)aLocation 
    self = [super init];
    if (self) 
        self.name = aName;
        self.location = aLocation;
    
    return self;


-(id)initWithWithCoder:(NSCoder)decoder 
    self = [super initWithCoder:decoder];
    if (self) 
       self.name = [decoder decodeObjectForKey:@"name"];
       self.location = [decoder decodeObjectForKey:@"location";
    
    return self;


-(void)encodeWithCoder:(NSCoder*)encoder 
    [encoder encodeObject:self.name forKey:@"name"];
    [encoder encodeObject:self.location forKey:@"location"];
    [super encodeWithCoder:encoder];


@end

有了这个,将places 数组保存到磁盘就像这样简单:

[NSKeyedArchiver archiveRootObject:places toFile:path];

解码同样简单:

places = [[KSKeyUnarchiver unarchiveObjectWithFile:path] retain];

【讨论】:

好的,谢谢!有用!但是我的程序在保存数据时崩溃了。我需要在 Place 类的构造函数中删除 self super 的初始化,程序保存成功!【参考方案2】:

要在数组中使用 writeToFile 对象,必须是支持 plist 的类型(NSDate、NSDate、NSString、NSArray、NSDictionary)

对数组中的对象实现 NSCoding 并使用 NSKeyedArchiver 进行序列化/反序列化。 写:

[NSKeyedArchiver archiveRootObject:myArray toFile:self.places];

阅读:

[NSKeyedUnarchiver unarchiveObjectWithFile:path];

更多信息可以在这里找到:

Persisting Custom Objects

【讨论】:

以上是关于使用 NSObjects 将文件保存到文档 NSMutableArray 的问题的主要内容,如果未能解决你的问题,请参考以下文章

使用代号将文件保存到电话文档

我是不是需要发布复制的 NSObjects - Objective-c

使用覆盖将图像保存到文档目录

使用共享扩展将图像保存到文档文件夹

如何将视频文件保存到文档目录

如何将 UIImage 保存到文档目录?