Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift 3: subclassing NSObject or not?

I have read some posts like this one about the difference between subclassing NSObject in Swift or just having its native base class with no subclassing. But they all are a bit old posts, and I am not clear about this topic.

When should you subclass NSObject? What is the actual difference between subclassing it and not subclassing? What is currently the recommendation in Swift?

like image 268
AppsDev Avatar asked Oct 09 '16 12:10

AppsDev


People also ask

Do Swift classes inherit from NSObject?

That means all UIKit classes ultimately come from NSObject , including all of UIKit. You don't have to inherit from NSObject in Swift, but you did in Objective-C and in fact there are some behaviors you can only have if you do inherit from it.

Why do we need NSObject in Swift?

NSObject exists to mark a class in Swift that you will provide that basic functionality — basically Objective-C needs you to build up from a base class with your functionality on top (That is, NSObject is a Universal Base Class).

What is an NSObject Swift?

The root class of most Objective-C class hierarchies, from which subclasses inherit a basic interface to the runtime system and the ability to behave as Objective-C objects.

Does UIView inherit from NSObject?

Only classes that inherit from NSObject can be declared @objc w/ UIView.


1 Answers

Apple's documentation about NSObject states the following as an introduction:

NSObject is the root class of most Objective-C class hierarchies. Through NSObject, objects inherit a basic interface to the runtime system and the ability to behave as Objective-C objects.

As this would suggest, you need to subclass NSObject for types introduced in your code whenever instances of that type need to behave like an Objective-C object (or the class itself, in some rarer cases).

I am not aware of super explicit Apple provided written guidance on when not to subclass NSObject, beyond suggesting reducing dynamic dispatch or presenting code reuse paradigms using that do not relying on subclassing but protocol extensions, i.e. code reuse that is generally more static dispatch and value type friendly). I believe it is fair to say though that most Swift programmers have taken hints from Apple, and Swift language features as signs to avoid introducing NSObject based types when the above-mentioned need is not there. That is, as a general rule, only introduce NSObject based types when you actually need the Objective-C dynamism, most commonly when you need to interface with Cocoa APIs (especially common when your code is UI related: e.g. view controllers, views).

As pointed out in an answer to the question you link to, with Objective-C style dynamism comes the performance of objc_msgSend based method dispatch. Although methods in Swift classes are also virtual, the compiler is able to use faster means of dispatching methods when you don't explicitly mark the methods with the @objc attribute – especially when Whole Module Optimization is toggled on, and even more so in Swift 3 where classes are not by default open for subclassing beyond the module that defines the type.

Beyond avoiding NSObject, you can also avoid class based reference types altogether in many cases when writing Swift. Take a look at for instance the value type WWDC videos linked above, or for example this blog post as an introduction. Briefly, using value types you gain good local reasoning, often avoid dynamic memory allocation and reference counting overhead (though not universally so – structs with reference types as fields being the caveat).

like image 112
mz2 Avatar answered Oct 13 '22 22:10

mz2