Не удается получить NSData в NSMutableArray - PullRequest
1 голос
/ 15 марта 2012

У меня есть массив объектов, которые я хочу сохранить в виде файла и перезагрузить обратно в мое приложение.Он сохраняет файл (с некоторыми данными внутри), но я не могу заставить его считывать обратно в массив 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 Ответ

1 голос
/ 15 марта 2012

Вам не хватает вызовов super в ваших методах encodeWithCoder: и initWithCoder:, но это только предположение. Почему бы не использовать NSUserDefaults для сохранения настроек?

Возможно, вы также захотите убедиться, что ваши объекты сохранены, с помощью синтезатора.

- (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
...