3 Stimmen

NSInteger und decodeInteger:forKey: Probleme

Ich habe die folgenden zwei Archivierungsmethoden:

    - (void) encodeWithCoder: (NSCoder *) encoder {
    [encoder encodeObject:self.exercises forKey:@"exercises"];
    [encoder encodeObject:self.title forKey:@"title"];
    [encoder encodeObject:self.description forKey:@"description"];
    [encoder encodeInteger:self.idnum forKey:@"idnum"];
    [encoder encodeInteger:self.rating forKey:@"rating"];
    [encoder encodeInteger:self.frequency forKey:@"frequency"];
    NSLog(@"Encoding!");

}

- (id) initWithCoder: (NSCoder *) decoder {
    self.exercises =   [[decoder decodeObjectForKey:@"exercises"] retain];
    self.title =       [[decoder decodeObjectForKey:@"title"] retain];
    self.description = [[decoder decodeObjectForKey:@"description"] retain];
    self.idnum =       [[decoder decodeIntegerForKey:@"idnum"] retain];
    self.rating =      [[decoder decodeIntegerForKey:@"rating"] retain];
    self.frequency =   [[decoder decodeIntegerForKey:@"frequency"] retain];
    NSLog(@"Decoding!");
    return self;
}

Und eine Überschrift:

    @interface Workout : NSObject{

    NSMutableArray *exercises; 
    NSString *title;
    NSString *description;
    NSInteger idnum;
    NSInteger rating;
    NSInteger frequency;
}

- (void) encodeWithCoder: (NSCoder *) encoder;
- (id) initWithCoder: (NSCoder *) decoder;

@property(nonatomic,retain) NSMutableArray *exercises; 
@property(nonatomic,retain) NSString *title;
@property(nonatomic,retain) NSString *description;
@property(nonatomic) NSInteger idnum;
@property(nonatomic) NSInteger rating;
@property(nonatomic) NSInteger frequency;
@end

Es scheint einfach genug. encodeInteger nimmt eine NSInteger, die ich es übergeben, und decodeIntegerForKey gibt eine NSInteger, aber ich bekomme diese seltsame Fehler:

Warnung: Ungültiger Empfängertyp 'NSInteger'

und wenn die Anweisung decodeIntegerForKey ausgeführt wird, erhalte ich einen exec bad access.

Warum ist das so?

8voto

Jon Hess Punkte 14197

Es gibt ein paar Probleme mit dem veröffentlichten Code. Erstens:

self.idnum =       [[decoder decodeIntegerForKey:@"idnum"] retain];

Dieser Code sendet 'retain' an einen NSInteger. NSInteger sind jedoch keine Objekte, sondern nur Skalare. Das ist illegal. Verwenden Sie stattdessen dies:

self.idnum =       [decoder decodeIntegerForKey:@"idnum"];

Dann dieser Code:

self.exercises =   [[decoder decodeObjectForKey:@"exercises"] retain];

Wird zu stark zurückgehalten und verursacht ein Leck. Da Sie erklärt Übungen wie:

@property(nonatomic,retain) NSMutableArray *exercises; 

Das "retain" bedeutet, dass der Setter beim Aufruf den übergebenen Wert behält, bevor er ihn in die Instanzvariable "exercises" einfügt. Sie behalten vor dem Aufruf der Setter aber, so dass eine doppelte behalten ist.

Sie können dies beheben, indem Sie Ihren Code entweder ändern:

exercises =   [[decoder decodeObjectForKey:@"exercises"] retain];

Oder:

self.exercises =   [decoder decodeObjectForKey:@"exercises"];

1voto

Rob Keniger Punkte 45562

Ist das Bereitstellungsziel für Ihr Projekt auf Mac OS 10.5 oder höher festgelegt? NSInteger wurde erst in Leopard eingeführt. Wenn Sie also auf Tiger abzielen, müssen Sie Implementierungen von NSInteger y -decode/encodeIntegerForKey:

Nebenbei bemerkt, sollten Sie es im Allgemeinen vermeiden, Accessoren zu verwenden, wenn Sie ivars in init-Methoden setzen. Normalerweise sollten Sie die Efeuwerte direkt setzen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X