将文件保存到带有对象的文档NSMutableArray时出现问题

时间:2011-08-12 09:53:26

标签: objective-c ios nsmutablearray ios-4.2

我是iOS新手开发者。 我写了一个小应用程序,用我的NSMutableArray对象保存NSObject数组。 应用程序执行保存但文件目录中未创建文件,应用程序无法读取。 这个问题都出现在模拟器和我的iPhone 3gs 4.2.1

我在NSMutableArray类中的appDelegate定义:

@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

My 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

那有什么不对?

谢谢你们。

2 个答案:

答案 0 :(得分:2)

在数组中使用writeToFile对象需要是plist能力类型(NSDate,NSDate,NSString,NSArray,NSDictionary)

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

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

读:

[NSKeyedUnarchiver unarchiveObjectWithFile:path];

可在此处找到更多信息:

Persisting Custom Objects

答案 1 :(得分:2)

你想要的是让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];