在 Objective C 中,自定义 init 方法必须调用父类(super class)的指定初始化程序。考虑以下用于 NSView 子类的自定义初始化方法:
- (void)initWithFrame:(CGRect)aFrame andName:(NSString *)aName {
if(self = [super initWithFrame:aFrame]){
//set up object
}
}
但是,MacRuby 只提供了 super
关键字,它只是尝试调用父类(super class)中的相同方法。但是,由于这是一个自定义初始化程序,父类(super class)没有这样的方法。
解决这个问题的标准方法是什么?我确实看到了这个问题:MacRuby custom initializers但我不能说我非常理解这个答案,它似乎也不是一个被广泛接受的解决方案。由于 MacRuby 现在比写那篇文章的时候早了几年,我希望现在有一个更清晰、标准的解决方案。
最佳答案
在 rubymotion 中(我认为 MacRuby 也有这种行为)有两种类型的类:使用 initialize
的纯 Ruby,以及从 objective-c 类派生的类。最好不要将两者混用。如果你是一个 objective-c 类的子类,你应该使用 init
方法。您的 initialize
方法永远不会被调用!
这是因为 NSObject##new
方法调用的是 init
,而不是 initialize
).
您上面的示例令人困惑,因为您调用的是 init
而不是 initWithFrame
。您必须调用父类的指定初始化器 - 在这种情况下,使用 super
。
如果您调用的初始化程序(在这种情况下,init
调用您的 初始化程序,则您使用了错误的初始化程序 - 在这种情况下无法逃避递归循环.
所以你不能完全选择在父级上调用哪个方法。但是,您可以使用自己的初始化方法:
def initWithTitle(title)
initWithFrame(CGRectZero)
@title = title
return self
end
我会这样写这个方法:
def initWithTitle(title)
initWithFrame(CGRectZero).tap do
@title = title
end # that way I never forget to return self
end
关于objective-c - 从 MacRuby 中的自定义初始化程序调用不同的父类(super class)初始化方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14617115/