naudecruywagen
naudecruywagen

Reputation: 388

What does @objc do under the hood?

I couldn't find anything specific to this in Apple's documentation.

Here is a scenario.

Objective-C class:

@implementation Superclass

- (instancetype)init {
    self = [super init];
    [self doSomething];
    return self;
}

- (void)doSomething {
    NSLog(@"\ndoSomething called from Superclass\n");
}

@end

Swift subclass:

class Subclass: Superclass {

    override init() {
        super.init()
        doSomething()
    }

    @objc func doSomething() {
        print("\n\ndoSomething called from Subclass\n")
    }

}

Using @objc in the method signature of doSomething in the subclass causes the method in the superclass never to be called i.e. only doSomething called from Subclass is printed to the console.

Removing @objc fixes the issue.

Why is this?

Upvotes: 0

Views: 231

Answers (2)

Cy-4AH
Cy-4AH

Reputation: 4585

When @objc used for class declaration means that you write Objective-C class with Swift.

@objc used for method declaration means that instead of swift's String, Dictionary, Notification etc. actually will be use Objective-C's NSString, NSDictionary, NSNotification and methods become available in Objective-C code.

Upvotes: 0

Martin R
Martin R

Reputation: 539975

@objc makes the method available to the Objective-C runtime, compare Attributes in the Swift Language Reference. Therefore

@objc func doSomething()

overrides the

- (void)doSomething 

instance method defined in the Objective-C superclass. Consequently, if self is an instance of Subclass then

[self doSomething];

calls the subclass method – no matter where that call is done. (Message dispatching is fully dynamic in Objective-C.) That's why the subclass method is called twice.

Without @objc, the Swift instance method is not visible to Objective-C, and does not override the superclass method.

Upvotes: 2

Related Questions