Cody Winton
Cody Winton

Reputation: 2989

Prevent Subclassing Objective-C Classes in Swift

I'm adding Swift interior annotations to my Objective-C classes. I'm trying to prevent my class from being subclassed:

__attribute__((objc_subclassing_restricted))
@interface CWTestFinalClass : NSObject
@end

This works as expected in Objective-C:

// Generates Error, as expected
@interface CWTestSubclass : CWTestFinalClass
@end

However, I'm still able to subclass in Swift

// Should fail, but works without error
class TestSubclass: CWTestFinalClass {

}

Question: How do I prevent Objective-C classes from being subclassed in Swift?

Upvotes: 1

Views: 445

Answers (1)

Alexander
Alexander

Reputation: 63399

Objective C does not have a final keyword, or anything like it. Even if a compile-time attribute or modifier did exist, it could trivially be sidelined by the use of the runtime APIs to dynamically create a subclass of any psuedofinal class.

The Swift compiler enforced that Swift could block attempts to subclass a final class, but that wouldn't stop Objective C from being able to do so (which isn't compiled through the Swift compiler). Thus, the objc_subclassing_restricted attribute was added, specifically to make clang enforce the illegality of subclassing final Swift classes.

There really isn't much of a benefit to making Objective C classes final, even if it were possible. Objective C is a much more dynamic language, that seems to follow Python's "we're all adults here" mantra.

The biggest reason to support final classes is inform the compiler which classes are candidates for de-virtualization. But Objective C always uses dynamic dispatch, and never does de-virtualization, anyway.

Upvotes: 2

Related Questions