Swift 3 - Dynamic VS @Objc

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



Leave a reply



Submit