简体   繁体   中英

UIVIew superclass object calling subclass method instead of method in its own scope

My super class defines a private method called "commonInit" which is only called at construction.

The super class is derived by 2 additional classes, each of which also implement a method called "commonInit"

While constructing the objects of the derived class I see in the debugger that the subclass method is called from the scope of the superclass.

This seems to be very dangerous behavior - even in a trivial case when by coincedence you "overwrite" your superclass private method

How can I overcome this behavior without renaming the method in the super class?

Example:

@interface ASuperView : UIView
@end

@implementation ASuperView
-(id)init
{
  self = [super init];
  if(self)
  {
    [self commonInit]; // BOOM - The derived view method is called in this scope
  }
  return self;
}

-(id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
  if(self)
  {
    [self commonInit];
  }
  return self;
}

-(void)commonInit
{
  //setup the view
}

@end

@interface ADerivedView : ASuperView

@end

@implementation ADerivedView
-(id)init
{
  self = [super init];
  if(self)
  {
    [self commonInit];
  }
  return self;
}

-(id)initWithFrame:(CGRect)frame
{
  self = [super initWithFrame:frame];
  if(self)
  {
    [self commonInit];
  }
  return self;
}

-(void)commonInit
{
  //setup the view for the derived view
}
@end

In this image PXTextMessageBox derived from PXTextBox

Both declare privately the method common init

在此处输入图片说明

There is no such thing as 'private' methods in obj-c. At best you can hide the existence of a method from consumers of your header, but by design anyone that has a reference to your object can call any method it implements - even if they don't have that method defined in the header. Your best bet will be to define a new method, say _private_commonInit, and not share that in your class header.

I believe this is actually by design. Polymorphism at its best even! .. self actually refers to the object that originally sent the message (which is not always the class instance where self appears) ... one way to solve this would be to chain the commonInit in the same way Init is chained ... a call to [super commonInit] will invoke the correct method from the subclass ...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM