无法将NSData导入NSMutableArray

时间:2012-03-15 07:00:45

标签: objective-c macos cocoa nsmutablearray nsdata

我有一个对象数组,我想将其保存为文件并重新加载回我的应用程序。它正在保存文件(里面有一些数据)但我无法将其读回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;
}

有人能指出我出错的方向吗?我很困惑: - (

提前致谢!

1 个答案:

答案 0 :(得分:1)

您错过了superencodeWithCoder:方法中的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