来自initWithCoder的值(int,struct-values)在此方法之外丢失

时间:2011-08-15 15:15:33

标签: objective-c cocoa osx-snow-leopard

我对objective-c很新,并且我认为这个任务非常简单。我使用Xcode 4.0.1,我的部署目标是OS X 10.6。

使用intsencodeWithCoder保存并加载一些纯C 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 个答案:

答案 0 :(得分:1)

如果您通过点语法将结构本身称为Objective-C属性,则不能使用Objective-C点语法来设置struct成员的值。事实上,编译器应该警告你。

为了说明,如果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对象属性的struct成员的值:

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

这只是问题的设定者,getter用点符号工作正常。

此外,您还应避免在‑init方法中使用访问者,而应直接设置ivars。

你需要得到这样的结论:

- (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;
}

答案 1 :(得分:0)

您的- (void)encodeWithCoder:(NSCoder *)encoder实施在哪里?如果你没有实现它可能是你的问题,如果你确实实现了它,请发布它。你也试图直接访问结构指针,所以你应该确保initWithCoder:中的self不是nil。

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