Should subclasses name the designated initializer in the nearest superclass?

I saw an example of code that made me wonder about calling the designated initializer in superclasses. Say I have a code:

@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 the UIView , not the UITableView . Should this code always call [UITableViewCell initWithStyle:reuseIdentifier:] or does it depend on the intent of the encoder?

+6
source share
2 answers

When subclassing, the directive is that the designated initializer must call the initializer of the assigned superclass.

Another recommendation is that the subclass should override the assigned superclass initializer to invoke the newly assigned initializer.

If the UITableViewCell follows this guide (and it executes, I tested using the category), it overrides the designated superclass initializer ( UIView initWithFrame: to call the newly assigned initializer ( initWithStyle:reuseIdentifier: . Therefore, if you call initWithFrame: on a UITableViewCell , it will call initWithStyle:reuseIdentifier: which in turn will call initWithFrame: on super ( UIView ).

Therefore, this will require an additional method call, but ultimately it will go through initWithStyle:reuseIdentifier:

Again, it is best practice that the designated initializer must call the designated initializer of the superclass and any other initializer that is not the designated initializer must call the designated initializer. From the "Assigned Initializer" :

General principle . The designated initializer in the class must, via the super message, invoke the assigned initializer in the superclass.

The designated initializers are tied to each other with messages up to super, while the other initialization methods are tied to the assigned initializers via messages for themselves.

+7
source

I agree that this depends on the attempt of the encoders, but the encoder should always try and use the designated initializer. Think about the initializers you might have written, they are probably doing extra work to keep your object in a convenient or desired state. If you override the initializer, as you do in your example, you must also call the overridden initializer. If this was a special initialization method, you would like to call the designated initializer, because for UITableViewCell this is the only way to publish 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: 
+1
source

Source: https://habr.com/ru/post/894863/


All Articles