Objective-C вызывает метод конкретного класса - PullRequest
2 голосов
/ 07 октября 2010

У меня есть класс, который имеет это в инициализаторе:

@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 init, а не SubFooClass * init.

Я не могу изменить способ инициализации объектов, поскольку я конвертирую проект из C # для использования в моем приложении для iPad.

Спасибо всем заранее

EDIT:

Из-за того, что кто-то спрашивает, вот мой заголовок:

@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

Ответы [ 2 ]

3 голосов
/ 07 октября 2010

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
1 голос
/ 07 октября 2010

Вы должны позвонить [super initWithSomeInt: someInt];в методе init вашего SubFooClass.;)

ДОБАВЛЕНО: Мне кажется странным, что вы пытаетесь вызвать init в iniWithSomeInt.Обычно нужно вызвать [super initWithSomeInt: someInt] в методе initIthSomeInt SubFooClass и изменить то, что вам нужно внутри предложения if.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...