我有一个对象数组,我想将其保存为文件并重新加载回我的应用程序。它正在保存文件(里面有一些数据)但我无法将其读回NSMutable数组。
对象是符合NSCoding协议的模型:
@implementation myModel
@synthesize name;
@synthesize number;
-(void) encodeWithCoder: (NSCoder *) encoder
{
[encoder encodeObject:name forKey:@"name"];
[encoder encodeInteger:number forKey:@"number"];
}
-(id) initWithCoder: (NSCoder *) decoder
{
name = [decoder decodeObjectForKey:@"name"];
number = [decoder decodeIntegerForKey:@"number"];
return self;
}
@end
所以我创建了这些对象的数组,然后保存它......
- (void) saveMyOptions {
// Figure out where we're going to save the app's data files
NSString *directoryPath = [NSString stringWithFormat:@"%@/Library/Application Support/MyAppDir/", NSHomeDirectory()]; // points to application data folder for user
// Figure out if that directory exists or not
BOOL isDir;
NSFileManager *fileManager = [[NSFileManager alloc] init];
[fileManager fileExistsAtPath:directoryPath isDirectory:&isDir];
// If the directory doesn't exist, create it
if (!isDir)
{
[fileManager createDirectoryAtPath:directoryPath withIntermediateDirectories:YES attributes:nil error:NULL];
}
// Assemble everything into an array of objects with options
NSMutableArray *savedPreferences = [[NSMutableArray alloc] init];
myModel *saveOptions = nil;
for (int i; i < [otherArray count]; i++)
{
saveOptions = [[myModel alloc] init];
[saveOptions setName:@"Some String"];
[saveOptions setNumber:i];
[savedPreferences addObject:saveOptions];
saveOptions = nil;
}
// Actually save those options into a file
NSData* saveData = [NSKeyedArchiver archivedDataWithRootObject:savedPreferences];
NSString *fileName = [NSString stringWithFormat:@"%@filename.stuff", directoryPath];
NSError *error = nil;
BOOL written = [saveData writeToFile:fileName options:0 error:&error];
if (!written)
{
NSLog(@"Error writing file: %@", [error localizedDescription]);
}
}
所以现在我尝试将数据加载回数组。这是我认为它正在崩溃的地方......
- (NSMutableArray *) loadOptions {
// Create file manager object
NSFileManager *fileManager = [[NSFileManager alloc] init];
NSData *saveData = nil;
// Find user directory path
NSString *directoryPath = [NSString stringWithFormat:@"%@/Library/Application Support/MyAppDir/", NSHomeDirectory()]; // points to application data folder for user
// Assign file name
NSString *fileName = [NSString stringWithFormat:@"%@filename.stuff", directoryPath];
// Create options array
NSMutableArray *myOptions = nil;
// If the file exists, fill the array with options
if ([fileManager fileExistsAtPath:fileName])
{
saveData = [NSData dataWithContentsOfFile:fileName];
myOptions = [NSKeyedUnarchiver unarchiveObjectWithData:saveData];
}
NSLog(@"%lu", [myOptions count]); // This ALWAYS reports 0!
NSLog(@"%lu", [saveData length]); // This reports a value of 236;
return myOptions;
}
有人能指出我出错的方向吗?我很困惑: - (
提前致谢!
答案 0 :(得分:1)
您错过了super
和encodeWithCoder:
方法中的initWithCoder:
来电,但这只是猜测。为什么不使用NSUserDefaults
来保存偏好?
您可能还希望确保使用合成的setter设置保留对象。
- (void)encodeWithCoder:(NSCoder *)encoder {
[super encodeWithCoder:encoder];
[encoder encodeObject:name forKey:@"name"];
[encoder encodeInteger:number forKey:@"number"];
}
- (id)initWithCoder:(NSCoder *)decoder {
self = [super initWithCoder:decoder];
if (self) {
self.name = [decoder decodeObjectForKey:@"name"];
self.number = [decoder decodeIntegerForKey:@"number"];
}
return self;
}
对于您的信息,NSKeyedArchiver
还有一种方法可以直接用于操作文件:
+ (BOOL)archiveRootObject:(id)rootObject toFile:(NSString *)path
和NSKeyedUnarchiver
:
+ (id)unarchiveObjectWithFile:(NSString *)path