2

イニシャライザにこれがあるクラスがあります:

@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

それはすべて元気でダンディです。私の問題は、サブクラスを実装するときに次のことです。

@implementation SubFooClass

-(id) init
{
     return [self initWithSomeInt:0];
}

-(id) initWithSomeInt:(int) someInt
{

     if (self = [super init]) // <--- Infinite loop (stack overflow :) )
     {
          // initialize other variables
     }
}

@end

基本的に、 「」ではなく「BaseFooClass」を具体的に呼び出す必要があります。initSubFooClassinit

プロジェクトをC#からiPadアプリケーションで使用するように変換しているため、オブジェクトの初期化方法を変更できません。

よろしくお願いします

編集:

誰かが尋ねたので、ここに私のヘッダーがあります:

@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
4

2 に答える 2

3

ランタイムがメソッドを関数呼び出しに変換する方法のため、Objective-C はこのようには機能しません。スーパークラスのメソッドを呼び出す場合でも、Self は常に割り当てられたクラスのインスタンスです。BaseClassFoo 用に指定されたイニシャライザを作成し、常にそこに移動する必要があります。したがって、次のようなことを行う必要があります。

@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
于 2010-10-07T13:19:50.800 に答える
1

[super initWithSomeInt:someInt]を呼び出す必要があります。SubFooClassのinitメソッドで。;)

追加:iniWithSomeInt内でinitを呼び出そうとするのは奇妙だと思います。通常は、SubFooClassのinitIthSomeIntメソッドで[super initWithSomeInt:someInt]を呼び出し、if句内で必要なものを変更します。

于 2010-10-07T13:01:02.207 に答える