JAL JAL - 6 months ago 44
Swift Question

What is the difference between declaring a protocol @objc and having it conform to NSObjectProtocol in pure Swift?

Consider two Swift protocols:

@objc protocol SomeProtocol { }

protocol SomeOtherProtocol: NSObjectProtocol { }


What is the difference between declaring a Swift protocol
@objc
or having it conform to
NSObjectProtocol
? I know that any protocol that does not
@objc
will not be bridged to Objective-C, but what is the difference between these two declarations in a pure Swift application? As I understand it,
@objc
should conform
SomeProtocol
to
NSObjectProtocol
through the top-level
SwiftObject
.

Answer

There are differences, but they can be a bit nuanced. In a nutshell, @objc gives you optional which you should need and doesn't work with structs. NSObjectProtocol on the other hand essentially just constrains implementations to be subclasses of NSObject.

Annotating a protocol as @objc means it is registered with the Objective-C runtime, allowing the protocol to have runtime specific features, namely optional requirements. It also means that the protocol cannot be used on a struct but it could be used on any class and likewise dictionaries and arrays holding it can be bridged to NSDictionary and NSArray. From a pure-swift perspective, there's probably no reason you would need to do, since that feature has largely been supplanted with protocol extensions.

When a protocol extends NSObjectProtocol, on the other hand, it can still be used on a struct but that struct will have to implement all the methods expected of NSObjectProtocol. That can be a daunting task. From a practical perspective, it really just forces you to make classes implementing SomeOtherProtocol be subclasses of NSObject somewhere up the chain.