Dienstag, Februar 18, 2020

Codieren und decodieren eine benutzerdefinierte Klasse mit NSKeyedArchiver

Habe ich eine benutzerdefinierte Klasse, die ich wünschte, zu speichern und zu laden. Die Klasse enthält ein NSDate, ein NSString, und ein NSNumber. Ich habe realisiert das NSCoding-Protokoll .h-Datei. Hier ist der code, den ich bisher haben. theDate ist ein NSDate. dername ist die NSString. homeAway ist der NSNumber.

-(void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:theDate forKey:@"theDate"];
[aCoder encodeObject:theName forKey:@"theName"];
[aCoder encodeObject:homeAway forKey:@"homeAway"];
}

-(id)initWithCoder:(NSCoder *)aDecoder {
if ((self = [super init])) {
    theDate = [aDecoder decodeObjectForKey:@"theDate"];
    theName = [aDecoder decodeObjectForKey:@"theName"];
    homeAway = [aDecoder decodeObjectForKey:@"homeAway"];
}
return self;
}

Bin ich mit dem nachstehenden code zu laden meine custom-Objekt. Wenn ich mit dem print-Objekt in der Debugger nur die homeAway zeigt sich als ein Tatsächliches Objekt. theDate und dername sagen 0x4e4f150 nicht angezeigt, zeigen Sie auf ein gültiges Objekt.

[gamesArray setArray:[NSKeyedUnarchiver unarchiveObjectWithFile:path]];  
Game *loadedGame = [gamesArray objectAtIndex:gameNumber];

Speichere ich die Daten mit dem folgenden code:

Ich diese aufrufen meiner Klasse und erstellen Sie ein neues Spiel (die benutzerdefinierte Klasse, die ich versuche zu speichern). Der code bis zu NSDate *aDate = [gameDate Datum]; ist irrelevant.

-(void)newGame {
if (homeAway != 0) {
    if (dateChanged == 1) {
        if ([nameField.text length] > 0) {
            [homeButton setImage:[UIImage imageNamed:@"HomeGray.png"] forState:UIControlStateNormal];
            [awayButton setImage:[UIImage imageNamed:@"AwayGray.png"] forState:UIControlStateNormal];
            [dateButton setImage:[UIImage imageNamed:@"DateGray.png"] forState:UIControlStateNormal];
            [nameField setBackground:[UIImage imageNamed:@"textField.png"]];
            NSDate *aDate = [gameDate date];
            NSString *aString = [[[NSString alloc] initWithString:[nameField text]] autorelease];
            UIApplication *app = [UIApplication sharedApplication];
            [[[(miShotTrackAppDelegate *)[app delegate] viewController] courtViewOne] newGame:aDate withName:aString andPlace:homeAway];
            [loadTable reloadData];
            datePicke = 0;
            homeAway = 0;
            dateChanged = 0;
            nameField.text = @"";
            [self goBack];
            [self autoSave];
        }
    }
}

}

Aus, dass die Methode, die ich rufen Sie die Methode newGame die

-(void)newGame:(NSDate *)theDate withName:(NSString *)theName andPlace:(int)homeAway {

Game *newGame = [[Game alloc] init];
NSDate *tDate = [NSDate new];
tDate = theDate;
[newGame setTheDate:tDate];
NSString *tString = [NSString stringWithString:theName];
[newGame setTheName:tString];
NSNumber *theNumber = [NSNumber numberWithInt:homeAway];
[newGame setHomeAway:theNumber];
[gamesArray addObject:newGame];
gameNumber = [gamesArray count] - 1;
NSString *path = [self findGamesPath];
[NSKeyedArchiver archiveRootObject:gamesArray toFile:path];
[newGame release];
}

Warum werden meine Objekte nicht speichern? Nicht kopieren meine Objekte haben etwas zu tun mit es? Ich bekomme einen Fehler auf der auskommentierte Zeile, die sagt „exc bad access“. Bitte um Hilfe…

1 Kommentar

  1. 6

    Du bist nicht der Implementierung-initWithCoder richtig. -decodeObjectForKey gibt autoreleased-Objekt. Also So wie du geschrieben hast die Methode, du bist am Ende mit baumelnden Zeiger für alle Spiel ivars. Ändern -initWithCoder zu:

    -(id)initWithCoder:(NSCoder *)aDecoder 
    {
      if ((self = [super init])) {
        [self setTheDate:[aDecoder decodeObjectForKey:@"theDate"]];
        [self setTheName:[aDecoder decodeObjectForKey:@"theName"]];
        [self setHomeAway:[aDecoder decodeObjectForKey:@"homeAway"]];
      }
      return self;
    }

    und es sollte für Sie arbeiten.

    • Vielen Dank… es hat funktioniert!!!
    • Danke dafür!!!! Sollte ich zu diesem Beitrag hinzufügen: vergessen Sie nicht, rufen Sie die super die Funktionen auch! Wenn Sie dies nicht tun, werden Sie am Ende mit seltsamen Ergebnissen. Also: if ((self = [super initWithCoder:aDecoder])) { im obigen Beispiel.

Kostenlose Online-Tests