Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When a subclass overrides a method, how can we ensure at compile time that the superclass's method implementation is called?

The classic example is:

- (void)viewDidLoad {
    [super viewDidLoad]; // Subclasses sometimes forget this line

    // Subclass's implementation goes here
}

What are some ways to ensure at compile time that UIViewController subclasses always call [super viewDidLoad] when they override [UIViewController viewDidLoad]?

like image 578
codeperson Avatar asked Jan 30 '14 01:01

codeperson


People also ask

What happens when a method overrides another method?

The ability of a subclass to override a method allows a class to inherit from a superclass whose behavior is "close enough" and then to modify behavior as needed. The overriding method has the same name, number and type of parameters, and return type as the method that it overrides.

When an overridden method is called from within a subclass it will always refer to the version of that method defined by the?

When an overridden method is called from within a subclass, it will always refer to the version of that method defined by the subclass. The version of the method defined by the superclass will be hidden.

When should you override a method in a subclass?

In Java, method overriding occurs when a subclass (child class) has the same method as the parent class. In other words, method overriding occurs when a subclass provides a particular implementation of a method declared by one of its parent classes.


1 Answers

If we're talking about custom classes, you can add the following to your superclass's method declaration:

__attribute__((objc_requires_super));

And if you want to ensure that all of your UIViewController subclasses call a method like [super viewDidLoad];, you could subclass UIViewController something like this:

@interface BaseViewController : UIViewController

- (void)viewDidLoad __attribute__((objc_requires_super));

// per Scott's excellent comment:
- (void)viewWillAppear:(BOOL)animated NS_REQUIRES_SUPER;

@end

@implementation BaseViewController

- (void)viewDidLoad {
    [super viewDidLoad];
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
}

@end

And then just subclass BaseViewController throughout your project, rather than subclassing UIViewController.

Any subclass of BaseViewController which implements viewDidLoad and does not call [super viewDidLoad]; (which in turn calls UIViewController's viewDidLoad) will throw a warning.


EDIT: I've edited the answer to include an example of NS_REQUIRES_SUPER, per Scott's excellent comment. The two examples (viewDidLoad and viewWillAppear:) are functionally equivalent. Though I imagine NS_REQUIRES_SUPER probably will autocomplete for you. I'll likely begin using this macro myself in the future.

like image 148
nhgrif Avatar answered Oct 13 '22 01:10

nhgrif