In Swift, I see some methods like:
@objc private func doubleTapGestureRecognized(recognizer: UITapGestureRecognizer)
I was wondering, when to use @objc? I read some documents, but they are saying when you want it to be callable in Objective-C, you should add @objc flag
However, this is a private function in Swift, what does the @obj do?
Swift generates code that is only readable to other Swift code. But if we need to interact with the Objective-C runtime, we need to instruct Swift what to do. Here comes @objc to make swift code available to Objective-C.
Performance. The official Apple website claims that Swift is 2.6 times faster than Objective-C. However some studies indicate that the difference is not as dramatic. Swift and Objective-C are both statistically typed languages that use the same iOS SDK and the high-quality Low Level Virtual Machine compiler.
To import a set of Objective-C files into Swift code within the same app target, you rely on an Objective-C bridging header file to expose those files to Swift. Xcode offers to create this header when you add a Swift file to an existing Objective-C app, or an Objective-C file to an existing Swift app.
private mean it visible only in Swift. so use @objc to visible in Objective-C. If you have a func to selector a private func in swift, it is required.
The @objc attribute makes your Swift API available in Objective-C and the Objective-C runtime.
See: https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html
https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/InteractingWithObjective-CAPIs.html
Another late answer, but none of the existing answers on this question really answer the OP's question, which is: why the heck would you need to use @objc
on a private
class member, if @objc
is there for interaction with Objective-C, and the member in question is private, meaning that even if you have Objective-C code in your project, it shouldn't be able to see the member anyway?
The reason is that, because many of the frameworks are written in Objective-C, sometimes Objective-C features are needed to interact with certain APIs.
For example, suppose I want to register for a notification via DistributedNotificationCenter
:
DistributedNotificationCenter.default.addObserver(self,
selector: #selector(somethingHappened(_:)),
name: someNotification,
object: nil)
For this to work, we need to be able to get the selector for the somethingHappened
method. However, selectors are an Objective-C concept, so if the method is not visible to Objective-C, it does not have a selector. Therefore, even if the method is private and should not be called by arbitrary outside code, it will need an @objc
in order for the DistributedNotification
code, which is written in Objective-C, to be able to call it via its selector.
Another common case where @objc
is needed is to support Key-Value Coding (KVC), especially on macOS, where KVC and KVO are used to implement Cocoa Bindings. KVC is, like many other systems in Cocoa, implemented in Objective-C, which has the effect of requiring KVC-compliant properties to be exposed to the Objective-C runtime. Sometimes, it makes sense for KVC-compliant properties to be private. One example is when you have a property that affects other properties:
@objc private dynamic var originalProperty: String
@objc private static let keyPathsForValuesAffectingDependentProperty: Set<String> = [
#keyPath(originalProperty)
]
@objc public var dependentProperty: String { return changeItSomehow(self.originalProperty) }
In this case, our actual stored property is private, but the dependent property, which we do expose to outside code, needs to send its notifications when the private property is updated. By marking the private property as @objc
, we can easily do that by setting up a KVC dependency—otherwise, we'd have to write code to manually send the notifications in the private property's willSet
and didSet
handlers. In addition, the static property that informs the KVC system that dependentProperty
is dependent on originalProperty
needs to be exposed to Objective-C so that the KVC system and find it and call it, but it's not relevant to clients of our code.
Also, a view controller in a macOS app that updates controls in its view using Cocoa Bindings as an implementation detail may make certain private properties KVC-compliant in order to bind those controls to them.
So as you see, there are times when a method or property may need to be exposed to Objective-C in order to interact with the frameworks, without necessarily needing to be visible to clients of your code.
@objc / dynamic
It's for compatibility: Once you import your Swift file/code into Objective-C based project.
And use that if you want your property/method to be accessed by Objective-C code or class.
Most of the time it happens when you are sub classing a Swift class of Objective-C base class.
A Swift class or protocol must be marked with the @objc attribute to be accessible and usable in Objective-C. This attribute tells the compiler that this piece of Swift code can be accessed from Objective-C. If your Swift class is a descendant of an Objective-C class, the compiler automatically adds the @objc attribute for you.
Here apple documentation that says about @objc
.
Using Swift from Objective-C
Language Interoperability Compatibility
Links Updated:
Looks like the links has been updated by apple.
@objc is a class attribute, so you use
@objc public class MyClass
It exposes the class' methods to Objective C classes, so you'll only use it if your class contains public functions
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With