In Objective C, a custom init method must call the superclass's designated initializer. Consider the following custom init method for a sublcass of NSView:
- (void)initWithFrame:(CGRect)aFrame andName:(NSString *)aName {
if(self = [super initWithFrame:aFrame]){
//set up object
}
}
However, MacRuby only offers the super
keyword, which simply tries calling the same method in the superclass. Since this is a custom initializer, however, the superclass has no such method.
What is the standard way of solving this? I did see this question: MacRuby custom initializers but I can't say I understand the answer very well, nor does it seem to be some broadly accepted solution. Since MacRuby is now a few years older than when that post was written, I'm hoping a clearer, standard solution now exists.
In rubymotion (and I think MacRuby shares this behavior) there are TWO types of classes: pure Ruby, which use initialize
, and classes derived from an objective-c class. It is best not to mix the two. If you are subclassing a objective-c class, you should use an init
method. your initialize
method will never get called!
This is because the NSObject##new
method calls init
, not initialize
(actually even this is an oversimplification, but the abstraction works).
your example above is confusing because you are calling init
instead of initWithFrame
. You MUST call the designated initializer of the parent class - in this case, using super
.
If the initializer you call (in this case, init
, calls your initializer, you're using the wrong one - there's no escaping the recursion cycle in that case.
So you can't exactly CHOOSE which method to call on the parent. You can, however, use your own init method:
def initWithTitle(title)
initWithFrame(CGRectZero)
@title = title
return self
end
I would write this method like this:
def initWithTitle(title)
initWithFrame(CGRectZero).tap do
@title = title
end # that way I never forget to return self
end