简体   繁体   中英

Should subclasses call the designated initializer in the immediate super class?

I've seen some sample code which has got me wondering about calling the designated initializer in the super classes. Say I have some code this:

@interface NewTableViewCell : UITableViewCell {
}
@end

@implementation NewTableViewCell 
- (id) initWithFrame: (CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        // Do some stuff
    }
return self;
}
@end

Note that initWithFrame is the designated initializer for UIView , not UITableView . Should this code always be calling [UITableViewCell initWithStyle:reuseIdentifier:] , or does it depend on the coder's intent?

When subclassing, the guideline is that the designated initializer has to call its super class' designated initializer.

Another guideline is that the subclass needs to override the superclass' designated initializer to call the new designated initializer.

If UITableViewCell follows this guideline (and it does; I tested with the help of a category), it overrides its superclass' designated initializer ( UIView 's initWithFrame: ) to call the new designated initializer ( initWithStyle:reuseIdentifier: ). Therefore, if you call initWithFrame: on UITableViewCell it will call initWithStyle:reuseIdentifier: , which in turn will call initWithFrame: on super ( UIView ).

Therefore, it will need an additional method call but it will eventually go through initWithStyle:reuseIdentifier: .

Again, the best practice is that the designated initializer has to call the super class' designated initializer and any other initializer that isn't the designated initializer has to call the designated initializer. From "The Designated Initializer" :

General principle : The designated initializer in a class must, through a message to super, invoke the designated initializer in a superclass.

Designated initializers are chained to each other through messages to super, while other initialization methods are chained to designated initializers through messages to self.

I agree it depends on the coders attempt but the coder should always try and use the designated initializer. Think about initializers you may have written, they probably do additional work for your object to be in a usable or desired state. If you are overriding an initializer like you are doing in your example you should call the overridden initializer as well. If that was a custom init method then you would want to call the designated initializer because for UITableViewCell 's that is the only way to set the reuseIdentifier publicly.

//Override initWithFrame
//Fine although it may not (should not) get called for a UITableViewCell
- (id) initWithFrame: (CGRect)frame {
    self = [super initWithFrame:frame];

//Design a custom initializer to gather parameters for supers default initializer
-(id)initWithCustomObject:(id)object style:(UI..Style)style reuseIdentifier:(NSString*)rid {
    //This should call initWithStyle:reuseIdentifier:

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