Swift 3 - dynamic vs @objc
A function/variable declared as @objc
is accessible from Objective-C, but Swift will continue to access it directly via static or virtual dispatch.
This means if the function/variable is swizzled via the Objective-C framework, like what happens when using Key-Value Observing or the various Objective-C APIs to modify classes, calling the method from Swift and Objective-C will produce different results.
Using dynamic
tells Swift to always refer to Objective-C dynamic dispatch.
This is required for things like Key-Value Observing to work correctly. When the Swift function is called, it refers to the Objective-C runtime to dynamically dispatch the call.
Does the @objc marker change the behavior of dynamic variables?
In Swift 4, dynamic
variables will give a compilation error if they do not have the @objc
attribute on them. So, you could say the ability to compile is an advantage of adding @objc
.
What's the mechanics behind extension's methods overriding with '@objc' attribute?
Extensions,
as the name already says, are supposed to extend/add/include methods
to an existing implementation, making them one of the most beautiful
things about Objective-C, and now Swift, since you can add code to a
class or framework you do not own. Therefore, it makes sense that
you’re not supposed to “replace” code in extensions, conceptually
speaking.
That’s why the compiler complains when you try to do it.
Also Check out this answer.
however this seems to be a support issue too, as swift compiler simply throw this error:
overriding non-@objc declarations from extensions is not supported.
According to Apple,
Extensions can add new functionality to a type, but they cannot
override existing functionality.
But that is not the case, as we are overriding from the extension not vice versa,
which takes us back to the declaration of extension
.
Extensions add new functionality to an existing class, structure, enumeration, or protocol type. This includes the ability to extend types for which you do not have access to the original source code (known as retroactive modeling). Extensions are similar to categories in Objective-C. (Unlike Objective-C categories, Swift extensions do not have names.) Here.
Going back to the legacy topic swift compiler vs Objc compiler,
Dynamic dispatch vs. Static dispatch .
And there is no official documentation from apple on why this is not supported from the swift compiler or if they have any future plans to fix this or consider it an issue at all.
However, there’s no such thing as Swift dynamic dispatch; we only have
the Objective-C runtime’s dynamic dispatch. That means you can’t have
just dynamic and you must write @objc dynamic. So this is effectively
the same situation as before, just made explicit.
And here is a great article talking about this topic deeply.
@synthesize vs @dynamic, what are the differences?
@synthesize will generate getter and setter methods for your property.
@dynamic just tells the compiler that the getter and setter methods are implemented not by the class itself but somewhere else (like the superclass or will be provided at runtime).
Uses for @dynamic are e.g. with subclasses of NSManagedObject
(CoreData) or when you want to create an outlet for a property defined by a superclass that was not defined as an outlet.
@dynamic also can be used to delegate the responsibility of implementing the accessors. If you implement the accessors yourself within the class then you normally do not use @dynamic.
Super class:
@property (nonatomic, retain) NSButton *someButton;
...
@synthesize someButton;
Subclass:
@property (nonatomic, retain) IBOutlet NSButton *someButton;
...
@dynamic someButton;
Realm forces to add @objc word while defining dynamic variables
That tutorial is written in September 2016, which is quite outdated.
It used to be that if you have a class that is exposed to Objective-C, then all its members are exposed to Objective-C. In Swift 4, things that are not marked with @objc
are not exposed to Objective-C, regardless of whether it is a member of a @objc
class.
Realm needs to do dynamic stuff on your properties, like KVO. That's why dynamic
is needed. But dynamic
is a feature exclusive to stuff that is exposed to Objective-C, which is why you need @objc
.
This is also why Realm can't handle Swift optionals, because they can't be bridged to Objective-C. You have to use RealmOptional<T>
.
In short, just add @objc
to your properties and everything will be fine.
Are public swift functions on ObjC objects dynamically or statically dispatched?
The Swift compiler will try to prove that a call to a method can only end up with a single implementation. If it can prove this then it will use static and not dynamic dispatch. Use of the "final" or "private" keyword, and whole module optimisation, will help with this.
Protocol required methods in swift are dynamic then how swift is to be said faster than objective c?
Well Read a little about static dispatch. In Swift these are value types :
Int, Double, String, Array, Dictionary, Set, Struct, Enum, Tuple
And value types use static dispatch because they don’t need inheritance. So in many cases these are static and fast.
In your example if you make protocol extension and methods of that extension would be static dispatch which makes Swift faster and rest you can read in the same example Whats the cause, Swift is supposed to be that much faster than Objective-C?.
extension Person{
// Dynamic dispatch coz required method
func hasLife()
{
print("True")
}
// static dispatch coz not required
func isAlive()
{
print("True")
}
}
When to use @objc in Swift?
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
Xcode 10.2 Swift 5: dynamic' property '' must also be '@objc'
You don't need to specify dynamic for Realm List types. Just
let openingHours = List<ShopHourRealm>()
will suffice.
Based on the examples here https://realm.io/docs/swift/latest/#models
import RealmSwift
// Dog model
class Dog: Object {
@objc dynamic var name = ""
@objc dynamic var owner: Person? // Properties can be optional
}
// Person model
class Person: Object {
@objc dynamic var name = ""
@objc dynamic var birthdate = Date(timeIntervalSince1970: 1)
let dogs = List<Dog>()
}
Related Topics
Swift Override Function in Extension
Set Custom Images to the Uibarbuttonitem But It Doesn't Show Any Image
What Is Build Object File Extension in iOS
Why Is This Code Not Recognising the Nsstring as Being Equal
Datefromstring Returns Nil for Some Values
Async Request Does Not Enter Completion Block
Swiftui Generic Pull to Refresh View
Google Maps iOS Sdk: Custom Icons to Be Used as Markers
How to Send Multiple Parameterts to PHP Server in Http Post
Is Possible to Simulate Touch Event Using an External Keyboard on iOS Jailbroken
This Class Is Not Key Value Coding-Compliant for the Key Xxxxxx
Error: Uicollectionview Must Be Initialized with a Non-Nil Layout Parameter
Sending a Private Message to Your Friends via Facebook iOS Sdk
Change Width of a Uibarbuttonitem in a Uinavigationbar
Create and Perform Segue Without Storyboards
iOS How to Detect Programmatically When Top View Controller Is Popped