Значения (int, struct-values) из initWithCoder теряются вне этого метода - PullRequest
0 голосов
/ 15 августа 2011

Я довольно новичок в Objective-C и застрял с довольно простой задачей, которую я предполагаю. Я использую Xcode 4.0.1, и моя цель развертывания - OS X 10.6.

Я сохраняю и загружаю некоторые простые значения C ints s и struct, используя encodeWithCoder и initWithCoder. Это работает довольно хорошо - сохраненные значения загружаются, и я могу NSLog их в методе initWithCoder.

Но когда я хочу использовать эти загруженные значения в другом методе, все они исчезают. Но я не могу понять, почему или где теряются ценности.

Вот соответствующие части моего кода:

Мой заголовочный файл:

@interface OptimiererZwoAppDelegate : NSDocument <NSApplicationDelegate,NSCoding> {

//Winkel in Grad
__strong struct bildanalyse { 
    float winkelo;
    float winkelr;
    ... here are some more variables…
    float skalfak;   
};

__strong struct bildanalyse *analyse;
__strong int16_t anzahlanalysewerte;


...some more stuff....
}
...
- (NSData *) dataOfType:(NSString *)aType error:(NSError **)outError;
- (BOOL) readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError;
- (void) encodeWithCoder: (NSCoder *) coder;
- (id) initWithCoder: (NSCoder *) coder;
...

@property __strong struct bildanalyse *analyse;
@property __strong int16_t anzahlanalysewerte;
...

А это мой файл реализации:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    ...some code...
    [self prepareApp]; 
}


-(void) prepareApp{
    NSLog(@"prepareApp");
    self.analyse = NSAllocateCollectable(sizeof(struct bildanalyse) * 256, 0); 
    self.anzahlanalysewerte = 0;
}


- (void) encodeWithCoder: (NSCoder *) coder{

    [coder encodeInt:self.anzahlanalysewerte forKey: @"anzahlanalysewerte"];

    for(int i=0; i< self.anzahlanalysewerte; i++){
        [coder encodeFloat:self.analyse[i].winkelo forKey: [NSString stringWithFormat:@"winkelo%d",i]];
        [coder encodeFloat:self.analyse[i].winkelr forKey: [NSString stringWithFormat:@"winkelr%d",i]];
        ...
        [coder encodeFloat:self.analyse[i].skalfak forKey: [NSString stringWithFormat:@"skalfak%d",i]];
    }
}

- (id) initWithCoder: (NSCoder *) coder{
    self = [super init];
    [self prepareApp]; 
    self.anzahlanalysewerte = [coder decodeIntForKey:@"anzahlanalysewerte"];

    for(int i=0; i< self.anzahlanalysewerte; i++){
        self.analyse[i].winkelo = [coder decodeFloatForKey: [NSString stringWithFormat:@"winkelo%d",i]];
        self.analyse[i].winkelr = [coder decodeFloatForKey: [NSString stringWithFormat:@"winkelr%d",i]];
        ...
        self.analyse[i].skalfak = [coder decodeFloatForKey: [NSString stringWithFormat:@"skalfak%d",i]];
    }
    return self;
}

Ответы [ 2 ]

1 голос
/ 16 августа 2011

Нельзя использовать точечный синтаксис Objective-C для установки значения членов структуры, если вы ссылаетесь на саму структуру через синтаксис точки как свойство Objective-C.Фактически, компилятор должен предупредить вас об этом.

Чтобы проиллюстрировать, что если foo является структурой с элементом bar, вы не можете сделать это:

anObjCobject.foo.bar = 42;

Однако,Вы можете назначить целую структуру этому свойству следующим образом:

foobar.bar = 42; // where foobar is a struct of the same type as foo
anObjCobject.foo = foobar;

Путаница, вероятно, связана с тем, что вы можете получить доступ к значению члена структуры, которое является свойствомОбъект Objective C с использованием точечной нотации:

NSLog("%lu", anObjCobject.foo.bar); //outputs 42, perfectly legal

Проблема заключается только в установщиках, геттеры работают нормально с точечной нотацией.

Кроме того, следует также избегать использования методов доступа в ‑initметоды, вы должны вместо этого установить ивары напрямую.

Вам понадобится что-то вроде этого:

- (id) initWithCoder: (NSCoder *) coder{
    if((self = [super init]))
    {
        [self prepareApp]; 
        anzahlanalysewerte = [coder decodeIntForKey:@"anzahlanalysewerte"];

        //self.analyse needs to be malloc'd to accomodate the size of anzahlanalysewerte as well
        for(int i=0; i< self.anzahlanalysewerte; i++)
        {

            bildanalyse foo;
            foo.winkelo = [coder decodeFloatForKey: [NSString stringWithFormat:@"winkelo%d",i]];
            foo.winkelr = [coder decodeFloatForKey: [NSString stringWithFormat:@"winkelr%d",i]];
            ...
            foo.skalfak = [coder decodeFloatForKey: [NSString stringWithFormat:@"skalfak%d",i]];

            analyse[i] = foo;
        }
    }
    return self;
}
0 голосов
/ 15 августа 2011

Где ваша реализация - (void)encodeWithCoder:(NSCoder *)encoder? Если вы не реализовали это, вероятно, это ваша проблема, если вы это реализовали, пожалуйста, опубликуйте это. Также вы пытаетесь получить прямой доступ к указателю структуры, поэтому убедитесь, что self не равен nil в initWithCoder:.

- (id) initWithCoder: (NSCoder *) coder{
    if((self = [super init]))
    {
        [self prepareApp]; 
        self.anzahlanalysewerte = [coder decodeIntForKey:@"anzahlanalysewerte"];

        //self.analyse needs to be malloc'd to accomodate the size of anzahlanalysewerte as well
        for(int i=0; i< self.anzahlanalysewerte; i++){
            self.analyse[i].winkelo = [coder decodeFloatForKey: [NSString stringWithFormat:@"winkelo%d",i]];
            self.analyse[i].winkelr = [coder decodeFloatForKey: [NSString stringWithFormat:@"winkelr%d",i]];
            ...
            self.analyse[i].skalfak = [coder decodeFloatForKey: [NSString stringWithFormat:@"skalfak%d",i]];
        }
    }
    return self;
}

Примечание. Когда вы соответствуете протоколу, вам не нужно добавлять методы этого протокола в заголовочный файл. Вы можете безопасно удалить как - (void) encodeWithCoder: (NSCoder *) coder;, так и - (id) initWithCoder: (NSCoder *) coder; из заголовка.

...