Objective-C调用特定类方法

发布于 2024-09-26 15:43:06 字数 1367 浏览 9 评论 0原文

我有一个类在初始化程序中有这个:

@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

我基本上需要专门调用 BaseFooClassinit 而不是 SubFooClass初始化。

我无法更改对象的初始化方式,因为我正在将项目从 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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

因为看清所以看轻 2024-10-03 15:43:06

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

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
苦妄 2024-10-03 15:43:06

你必须调用 [super initWithSomeInt:someInt];在 SubFooClass 的 init 方法中。
;)

添加:
我认为你尝试在 iniWithSomeInt 中调用 init 很奇怪。通常的做法是在 SubFooClass 的 initIthSomeInt 方法中调用 [super initWithSomeInt:someInt] 并更改 if 子句中所需的内容。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文