我对objective-c很新,并且我认为这个任务非常简单。我使用Xcode 4.0.1,我的部署目标是OS X 10.6。
使用ints
和encodeWithCoder
保存并加载一些纯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;
}
答案 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;
。