使用自定义 init 进行 NSCoding
我有一个名为“Defense”的类,其自定义 init 方法如下:
// initialize the defense unit and add the sprite in the given layer
- (id) initWithType:(DefenseType)tType andInLayer:(CCLayer *)layer {
NSString *fileName;
fileName = [NSString stringWithUTF8String:defenseStructuresFile[tType]];
if ( (self = [super initWithFile:fileName]) ) {
type = tType;
maxHealth = defenseStructuresHealth[tType];
health = maxHealth;
mapRef = (SkirmishMap *)layer;
}
return self;
}
现在我正在使我的类 NSCoding
兼容,这需要以下 2 个方法:
- (id) initWithCoder:(NSCoder *)decoder
- (void) encodeWithCoder:(NSCoder *)encoder
当我通常分配“Defense”的实例时,我代码如下:
Defense *twr;
twr = [[Defense alloc] initWithType:type andInLayer:mapRef];
当我想恢复已保存的 Defense 对象实例时,我将其编码为
twr = [[decoder decodeObjectForKey:kDefense] retain];
但在上面的代码中,我无法传递“type”和“mapref”参数,这些参数是初始化
所必需的> 对象...
防御类派生自 CCSprite
并且由于 CCSprite
不符合 NSCoding
,因此可以调用 (self = [super initWithFile:fileName ])
来自我的 initWithCoder
方法。但我需要 type
参数来确定要传递给 ccsprite's
initWithFile 的文件名。
那么在这种情况下我该怎么办呢? 我应该改变我的课程设计吗?如果是,怎么办?
任何好的想法/建议都将受到高度赞赏...:)
I have a class named "Defense" with custom init method as below:
// initialize the defense unit and add the sprite in the given layer
- (id) initWithType:(DefenseType)tType andInLayer:(CCLayer *)layer {
NSString *fileName;
fileName = [NSString stringWithUTF8String:defenseStructuresFile[tType]];
if ( (self = [super initWithFile:fileName]) ) {
type = tType;
maxHealth = defenseStructuresHealth[tType];
health = maxHealth;
mapRef = (SkirmishMap *)layer;
}
return self;
}
now i am making my class NSCoding
compatible, which requires the following 2 methods:
- (id) initWithCoder:(NSCoder *)decoder
- (void) encodeWithCoder:(NSCoder *)encoder
When I normally allocate an instance of "Defense", I code as follows:
Defense *twr;
twr = [[Defense alloc] initWithType:type andInLayer:mapRef];
and when I want to restore a saved instance of Defense object I code as
twr = [[decoder decodeObjectForKey:kDefense] retain];
But in the above code I cant pass the "type" and "mapref" parameters, which are very much required to initialize
the object...
The Defense class derives from CCSprite
and since CCSprite
doesn't conform to NSCoding
, it is fine to call (self = [super initWithFile:fileName])
from my initWithCoder
method. But I require the type
parameter to determine the filename to be passed to ccsprite's
initWithFile.
So what would I do in this situation?
Should I change my class design? if yes, how?
Any good ideas/suggestions are highly appreciated... :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您可以执行以下操作:
当输入您的方法(甚至是
init
的)时,self
始终会被设置。它只是一个变量(或者更准确地说:一个参数)。这就是为什么[self release]; return nil;
即使在调用super
之前也会起作用。当您调用self = [super initWithFoo:];
时,您将覆盖self
。这样做是因为您的超类可能会执行[self release]; return nil;
或分配一个具体的子类并返回它(当使用类簇时)。因此,在调用 super 的初始化程序之前,覆盖实例变量是不安全的,但使用普通的堆栈变量(甚至全局变量)是可以的。You can do something like this:
When your methods are entered (even
init
's) thenself
is always set. And it's just a variable (or to be more precise: an argument). This is why[self release]; return nil;
will work even before callingsuper
. When you callself = [super initWithFoo:];
you're overwritingself
. This is done because your super class might do[self release]; return nil;
or allocate a concrete subclass and return that instead (when using a class cluster). So before you call super's initializer, it's not safe to overwrite instance variables, but it's OK to use normal stack variables (or even global variables).