Why should I call self=[super init]

ghz 7months ago ⋅ 62 views

Let's say I create my class and its init method. Why should I call and return value of superclass init assigned to self? Which cases it covers?

I would appreciate examples why would I need it for Cocoa superclass and non-Cocoa.

Answers

Calling the superclass's init method and assigning its return value to self is a standard practice in object-oriented programming, particularly in languages like Objective-C and Swift. This practice ensures that the object is properly initialized and inherits any setup or initialization logic defined in its superclass. Here's why you should do it:

1. Ensures Proper Initialization:

When you create a subclass, it inherits properties and behaviors from its superclass. By calling the superclass's init method, you ensure that the superclass's initialization logic is executed, setting up any inherited properties and ensuring that the object is in a valid state. This is essential for the correct functioning of the subclass.

2. Allows Customization and Initialization:

By calling the superclass's init method, you have the opportunity to customize the initialization process for your subclass. You can perform additional setup specific to your subclass before or after calling the superclass's init method. This allows you to tailor the initialization process to the needs of your subclass.

3. Handles Inherited Initializers:

In Cocoa and Cocoa Touch frameworks, many classes provide designated initializers that must be called to properly initialize an object. By calling the superclass's designated initializer (typically init or initWithFrame: for views), you ensure that any required setup is performed. Failure to call the superclass's initializer may lead to undefined behavior or runtime errors.

Examples:

Cocoa Superclass (Objective-C):

@interface MyCustomView : UIView

@property (nonatomic, strong) UILabel *titleLabel;

@end

@implementation MyCustomView

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame]; // Call superclass's designated initializer
    if (self) {
        // Perform additional setup for MyCustomView
        self.titleLabel = [[UILabel alloc] initWithFrame:CGRectZero];
        [self addSubview:self.titleLabel];
    }
    return self;
}

@end

In this example, MyCustomView is a subclass of UIView. By calling [super initWithFrame:frame], we ensure that the superclass's initialization logic for UIView is executed, setting up the basic view properties. Then, we perform additional setup specific to MyCustomView, such as creating a titleLabel and adding it as a subview.

Non-Cocoa Superclass (Non-Objective-C):

class Vehicle {
    var numberOfWheels: Int
    
    init(numberOfWheels: Int) {
        self.numberOfWheels = numberOfWheels
    }
}

class Car: Vehicle {
    var color: String
    
    init(numberOfWheels: Int, color: String) {
        self.color = color
        super.init(numberOfWheels: numberOfWheels) // Call superclass's init
    }
}

In this example (written in Swift), Vehicle is a superclass with a designated initializer init(numberOfWheels:). Car is a subclass of Vehicle with an additional property color. By calling super.init(numberOfWheels: numberOfWheels), we ensure that the superclass's initialization logic for Vehicle is executed before performing additional setup specific to Car.

Summary:

In both Cocoa and non-Cocoa scenarios, calling the superclass's init method and assigning its return value to self is crucial for proper object initialization and customization. It ensures that the superclass's initialization logic is executed and allows for subclass-specific setup. Failure to call the superclass's initializer may lead to undefined behavior or runtime errors.