Не може да получи NSData в NSMutableArray

Имам масив от обекти, които искам да запазя като файл и да презаредя обратно в приложението си. Той запазва файла (с някои данни вътре), но не мога да го накарам да го прочете обратно в NSMutable Array.

Обектите са модели, които отговарят на протокола 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;
}

Може ли някой да ме насочи в посоката къде греша? Съвсем объркан съм :-(

Благодаря предварително!


person Matthew Jones    schedule 15.03.2012    source източник


Отговори (1)


Липсват ви 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
person Erik Aigner    schedule 15.03.2012
comment
супер определено беше част от него. Благодаря ти за това! Втората част беше, защото, като идиот, не присвоих i=0, когато зациклях, за да запълня масива с обекти, които исках да запазя. Следователно цикълът никога не се изпълняваше, защото бях нула... Хубаво. Благодаря ви много за помощта! - person Matthew Jones; 16.03.2012
comment
Дори не видях липсващото i присвояване. - person Erik Aigner; 16.03.2012