I have a class that has this in the initializer:
@implementation BaseFooClass
-(id) init
{
if (self = [super init])
{
// initialize instance variables that always need to start with this value
}
return self;
}
-(id) initWithSomeInt:(int) someInt
{
if (self = [self init]) // <-- I need to make sure that I am calling BaseFooClass's init here, not SubFooClass's, does that make sense?
{
self.someInt = someInt;
}
return self;
}
@end
That is all fine and dandy. My problem is that when I implement the subclass:
@implementation SubFooClass
-(id) init
{
return [self initWithSomeInt:0];
}
-(id) initWithSomeInt:(int) someInt
{
开发者_开发百科if (self = [super init]) // <--- Infinite loop (stack overflow :) )
{
// initialize other variables
}
}
@end
I basically need to specifically call the BaseFooClass
's init
rather than the SubFooClass
's init
.
I cannot change the way the objects are initialized, as I am converting a project from C# to use in my iPad application.
Thank you all in advance
EDIT:
Due to someone asking, here is my header:
@interface BaseFooClass : NSObject
// implicit from NSObject
// -(id) init;
-(id) initWithSomeInt:(int) someInt;
// more methods
@end
@interface SubFooClass : BaseFooClass
// implicit from NSObject
// -(id) init;
// implicit from BaseFooClass
//-(id) initWithSomeInt:(int) someInt;
@end
Objective-C doesn't work this way because of the way the runtime converts methods into function calls. Self is always an instance of the allocated class, even when invoking the super-class's methods. You need to create your designated initializer for your BaseClassFoo and always go there. So you should be doing something like this:
@implementation BaseFooClass
-(id) init
{
return [self initWithSomeInt:0]; // redirect super class's designated initializer
}
-(id) initWithSomeInt:(int) someInt
{
if ((self = [super init])) // Designated initializer always calls into super class's designated initializer (in this case, NSObject's designated initializer is init
{
self.someInt = someInt;
}
return self;
}
@end
@implementation SubFooClass
// Here we don't override init because our super class's designated initializer
// is initWithSomeInt:
// -(id) init
// {
// return [self initWithSomeInt:0];
// }
// we override this because it's our superclass's designated initializer, plus it
// is ours as well
-(id) initWithSomeInt:(int) someInt
{
if ((self = [super initWithSomeInt:someInt]))
{
// initialize other sub-class specific variables
}
}
@end
You have to call [super initWithSomeInt:someInt]; in the init method of your SubFooClass. ;)
ADDED: I think is weird you try to call init within iniWithSomeInt . The usual thing would be to call [super initWithSomeInt:someInt] in initIthSomeInt method of SubFooClass and change what you need inside the if clause.
精彩评论