用于多级继承的Objective C [self init]层次结构

时间:2013-10-28 12:58:28

标签: ios objective-c inheritance dynamic multiple-inheritance

我有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];
}

4 个答案:

答案 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;
}