According to Apple :
When you mark a member declaration with the dynamic modifier, access to that member is always dynamically dispatched. Because declarations marked with the dynamic modifier are dispatched using the Objective-C runtime, they’re implicitly marked with the #objc attribute.
According to Wikipedia:
dynamic dispatch is the process of selecting which implementation of a polymorphic operation (method or function) to call at run time.
Dynamic dispatch is often used in object-oriented languages when different classes contain different implementations of the same method due to common inheritance. For example, suppose you have classes A, B, and C, where B and C both inherit the method foo() from A. Now suppose x is a variable of class A. At run time, x may actually have a value of type B or C and in general you can't know what it is at compile time.
Right now, I'm studying the dependency injection framework : Typhoon and when I open the sample project for Swift in all the classes that inherit from the Objective-C class TyphoonAssembly all the methods relatives to inject dependencies have the dynamic modifier included in the following way :
public dynamic func weatherReportDao() -> AnyObject {
return TyphoonDefinition.withClass(WeatherReportDaoFileSystemImpl.self)
}
I thought that I'm missing something, but I don't understand where is the polymorphic operation (method or function) to call at run time here.
What's is the purpose of the dynamic dispatch here?
The answer to your question is addressed in this post:
https://github.com/appsquickly/typhoon/wiki/TyphoonAssembly
Basically at runtime the Typhoon Framework is going to replace your method with its own routine that implements the features of the framework and calls your method to do whatever work you've defined for it.
In order for the framework to be able to replace the method, the method must be dynamically dispatched.
Related
After seeing the video here, i got confused about the use of final keyword.
Here below is an example image from the video
Here there are two classes Pet as parent class and Dog as child class, and we have function implementation of makeNoise(p) which takes Pet instance as parameter. But behind the scene compiler inserts few more lines to this method for checking class.
Since makeNoise(p) takes parameter as Pet instance, compiler should directly call the property "name" from the Pet class, as the method parameter is for this class.
Why would compiler be worried about the overriding the property in child class, because the parameter is a Pet instance and compiler knows it. isn't it?
My question may looks silly but if someone can explain it more clearly, i would appreciate it.
The parameter of makeNoise(p: Pet) must be a Pet, but it does not to be an immediate instance of Pet itself. Since Dog is a subclass of Pet, it is also a Pet. Therefore, in Swift it is perfectly valid for someone to pass a Dog instance into makeNoise, in which case the overridden version of noise will be called. Also, this dog may have chosen a different value for name.
Dynamic Type
This is called the 'dynamic type' of p. The compile-time type of p is Pet, but the compiler must account for the fact that the run-time type of p might be a Pet subclass that overrides something. This is called the 'dynamic type' of p. In Swift 1 and 2, which were in use at the time of WWDC 2015, use the .dynamicType syntax on an object to determine its runtime type. Swift 3 uses the type(of: object) global function. This is not something you'll need very often, but it demonstrates how the compiler allows subclasses to act as their parent and still override things.
final
final tells the compiler that either the class will not be subclassed, or the property or method will not be overridden. This way it won't need to check for overrides.
Changes in Swift 3
This year's WWDC 2016 session on Swift performance did not mention the final keyword once, if I remember correctly, however. While it is still available in Swift 3 and serves the same purpose, there are new ways to prevent subclassing and overriding. This is via Access Control. Swift 3 introduces the open keyword as distinct from public.
public – The object, property, method, etc. is accessible by anyone inside or outside the module
open – The class or method is not only accessible by anyone, but may also be subclassed (in the case of classes) or overridden (in the case of methods).
I am not sure if this, like final, communicates to the Swift compiler that it does not need to do its extra type checking.
Does Swift keep the the method lookup list when compiled or does it call a function in a specific memory location?
Best regards.
Regarding this: http://davedelong.tumblr.com/post/58428190187/an-observation-on-objective-c
I would recommend you have a look at the below links, especially the first one because it explains the concepts with examples from C++ and Objective-C, in order to have a better understanding of the difference between static, late and dynamic dispatch (for methods).
In a nutshell:
Static dispatch
The function and its implementation is determined at compile time and thus can’t fail at runtime (because the compiler will not continue the compilation process unless the binding is successful).
Late dispatch
The function is determined at compile time, but the actual implementation depends on the type of the object at runtime. Important for inheritance. The compiler will check if the the class or any of its parents have the function declared, but its up to the runtime to choose which implementation to use. The late binding can be implemented using virtual tables like in the case of C++.
Dynamic dispatch
The function is determined at runtime, which in the case of Objective-C can be called by name and thus can fail at runtime if the receiver (object) doesn't implement or inherit a method that can respond to a specified message.
References
What is the difference between Dynamic, Static and Late binding?
What is early and late binding?
What is the difference between dynamic dispatch and late binding in C++?
In ObjC, it is using Messaging, static binding, dynamic typing, dynamic binding, dynamic method resolution, dynamic loading, introspector and so on.
Importantly, the core method objc_msgSend is responsible for taking the selector you're sending and the object you're sending it to, and looking that up in the class method tables to figure out exactly which piece of code is supposed to handle it.
My concerns here are:
Is Swift doing something similar like ObjC on runtime?
How does Swift runtime find the implementation code for some object/class method?
In ObjC, classes and objects are compiled to some runtime types such as C struct on runtime. Then what are such classes and objects compiled to on runtime in Swift?
Does Swift runtime have something like class / meta class / isa pointer / super pointer?
In short there are Dynamic and Static types of method call dispatching.
Static - the function address to be called is determined in the compilation time, so that expense of such call is similar to C-function calling. This mechanism is used for private methods or final classes methods call dispatching.
Dynamic dispatching is mechinism which allows to implement polymorphism concept of OOP - the function address to be called is determined in running time. Swift has two subtypes of it:
2.1. Obj-C - you already described in the question. This mechanism is used when object inherits from NSObject or calling method has #objc prefix.
2.2. Virtual table based (like in C++) - there is similar witness tables. What it does during method call dispatching is just single arithmetic operation - calculation of actual function address based on function offset in the base class witness table and the object class witness table location. So that's a relatively cheap operation comparing to Obj-C. It explains why "pure" Swift approximates to C++ performance.
If you don't mark you method with private keyword or your class is not final and same time you class is "pure" Swift (it does not inherit NSObject) then this virtual table based mechanism is used. It means that all the methods by default are virtual.
P.S.
Helpful link for proving my vision regarding "Types":
https://developer.apple.com/swift/blog/?id=27
"Subtypes" explanation is based on my understanding.
In Swift it's not necessary to prefix classes anymore as their module acts as the namespace.
What about prefixing extension functions? For example:
extension UIImage {
public func hnk_hasAlpha() -> Bool { ... }
}
On one hand Swift is not dynamic so collisions would generate compiler errors.
But what happens if compiled code runs in a future iOS/OS X version in which one of my extension methods is added? Would methods in different modules be considered different symbols even if they have the same signature?
Does it make a difference if the extended class is a NSObject subclass or a pure Swift class?
There's some subtlety here:
Extensions of Objective-C types are implemented as Objective-C categories, with all that implies.
Extensions of Swift types, however, are only in effect where visible due to imports. This means that you can't accidentally stomp on a private system method (whether now or one introduced in the future), and if the system introduces a public method with the same name as yours, you'll get a compile-time failure when you rebuild, but your existing app won't break.
You should check those threads also:
Name collisions for extension methods from different frameworks - quote from thread:
regardless the application code imports which Framework, it seems, the actual called implementation depends on the order in Linked Frameworks and Libraries in "First come, first served" manner. But, as far as I know, this behavior is not guaranteed.
and Swift Extension: same extension function in two Modules which also confirms the same problem.
So based on that for Objective-C objects such as UIImage from your example name collisions are possible and you might see unexpected behaviour if there will be two methods with the same name in two different extensions for Objective-C object.
What does external mean in Dart? For example: external DateTime._now();
I'm new to Dart, I can't find documentation for external, so can you give an example to help explain?
9.4 External Functions
An external function is a function whose body is provided separately from its
declaration. An external function may be a top-level function (17), a method
The body of the function is defined somewhere else.
As far as I know this is used to fix different implementations for Dart VM in the browser and Dart VM on the Server.
When we make an external function inside a class like toString()
external String toString();
means this method is abstract and the child of the parent class will add the function body, that's because in Dart we only can make an abstract class.
Summary:
external function = abstract function in not abstract classes
I don't think external keyword is meant to be used to mark methods as abstract, even if that's possible
It's enough to leave a method with no implementation to set it abstract, inside an abstract class
It's the equivalent of declare in TypeScript, and extern in C#, those are used for interoperability with other runtimes, which means you're telling the compiler "Don't worry about this method's implementation, I promise it will exist at runtime", the runtime may be in C or Javascript or whatever
In case, if you are wondering why or where should I even use external keyword, here is a one more example for Flutter.
class MyStruct extends Struct {
#Int32()
external int a;
#Float()
external double b;
external Pointer<Void> c;
}
Sometimes, but not often when you play with native libraries, in this case with Struct to access native struct's field in memory. Under Struct We must declare all fields as external because it will be external fields from dart:ffi (C / C++).
So, external is more than just way to declare "abstract method".
9.4 External Functions
An external function is a function whose
body is provided separately from its
declaration.
What this does mean is that you define the function, but without implementation. It's exactly how you define the abstract method, but the only difference is that with external you don't implement the method in dart but in C or something else.
Something like String class it can be considered as external functions except that the String class it marked with #pragma('vm:entry-point') which make the entire class use native code.
See the following example to understand:
This dart's side.
https://github.com/dart-lang/sdk/blob/main/sdk/lib/core/string.dart#L711
This the implementation in C++.
https://github.com/dart-lang/sdk/blob/main/runtime/lib/string.cc#L467-#L472
In my opinion it is an equivalent of Java native keyword. For example, since current time milliseconds is implemented differently on Android, iOS, Linux etc, DateTime.now().millisecondsSinceEpoch will be linked to different implementations at runtime. So it is not initially known how this method will look like. For this reason it is marked as external meaning it is platform dependent.