我有A类,它继承了B类。并希望实现类似下面的东西。但是由于动态类型转换,init方法会得到递归调用。 有没有办法实现这样的?有什么建议吗? (不改变子类中'init的名字?
@interface A : NSObject
@property NSData * data;
@end
@implementation A
- (id) init {
self = [super init];
/* want to do some default initialization here
for this class and all of its subclasses. */
// ... ...
return self;
}
/* This [self init] get recursed.
But how can I force this class and all of its subclass to call [self init] above,
not to call the subclass's init method. */
- (id) initWithData:(NSData *)d {
self = [self init];
self.data = d;
return self;
}
@end
@interface B : A
@end
#import "B.h"
@implementation B
- (id) init {
self = [super initWithData:nil];
// some subclass specific init code here ...
return
}
@end
使用B,
- (void) testInit{
B * b = [[B alloc] init];
}
答案 0 :(得分:6)
您在实现中调用[self init]
导致递归问题。
以这种方式实施:
- (id) init {
self = [super init];
//Basic empty init...
return self;
}
- (id) initWithData:(NSData *)d
{
self = [super init]; //<---- check this line.
if(self)
{
self.data = d;
}
return self;
}
//如果您只想编写一些初始化代码,则以下内容可以正常工作.....
-(void)oneTimeWrittenInitCode:(id)mySelf
{
//your init code which you wish to write one time goes here...
}
- (id) init {
self = [super init];
if(self)
{
[self oneTimeWrittenInitCode:self];
}
return self;
}
- (id) initWithData:(NSData *)d
{
self = [super init];
if(self)
{
[self oneTimeWrittenInitCode:self];
self.data = d;
}
return self;
}
答案 1 :(得分:1)
查找“指定的初始化程序”模式。它描述了如何在类层次结构中安排初始化方法和便捷构造函数(a.k.a.工厂方法)。
答案 2 :(得分:1)
这是上面提到的指定初始化模式的一个例子,
#import ”Person.h”
@implementation Person
-(id) initWithAge:(int)theAge AndHeight:(int)theHeight AndName:(NSString *)theName {
if (self = [super init]){
_age = theAge;
_height = thefleight;
_name = theName;
}
return self;
}
-(id) initwithAge:(int)theAge AndHeight:(int)theHeight {
return [self initWithAge:theAge AndHeight:theHeight AndName:nil];
}
-(id) initwithAge:(int)theAge {
return [self initWithAge:theAge AndHeight:0];
}
- (id)init {
return [self initwithAge:0];
}
@end
答案 3 :(得分:0)
应该是:
- (instancetype) initWithData:(NSData *)d
{
if(self = [super init])
{
_data = d;
}
return self;
}