From the previous analysis, structs are value types and classes are reference types. Where are the structs and class methods stored? Let’s analyze it
Static distributed
Function of the value type object is static call call way, namely direct address calls, call a function pointer, the function pointer upon the completion of the compile, link, the address of the current function is defined, and in the process of executing code just jump straight to this address to perform the corresponding method and stored in the code segment, and structure inside don’t deposit method. So it can be called directly from the address.
Dynamic dispatch
The methods declared in the class are scheduled using v-table. V-table in SIL looks like this:
// Declare the sil_vtable keyword 1 decl ::= sil-vtable // declare the sil_vtable keyword 1 decl ::= sil-vtable // declare the sil_vtable keyword 1 decl ::= sil-vtable; Sil-vtable-entry ::= sil-decl-ref ':' sil-linkage? sil-function-na meCopy the code
Let’s look at it through a simple example
class LGTeacher {
func teach(){}
func teach2(){}
func teach3(){}
func teach4(){}
@objc deinit{}
init(){}
}
Copy the code
throughSIL source file
See it in SILv-table
, as shown in the figure below
According to the figure above,
sil_vtable
Key words:LGTeacher
: Indicates yesLGTeacher
A function list of classes- The second is that the life of the current method corresponds to the name of the method
- Essence: The essence of a function table is similar to what we understand
An array of
, the statement inInside the class
In the process without any keyword modification,Continuous deposit
In our currentAddress space
In the
By looking at the source code, we find that its internal encoding is through the for loop, and then offset+index offset, and then get method, and store it into the memory after the offset, from here we can verify that the function is stored continuously.
It can be concluded that for functions in class, the class method schedule is via V-taable, which is essentially a contiguous memory space (array structure).
The location of the function declaration also leads to different distribution methods. If we declare a function in an extension of the class, this is a direct call.
The reason is that subclass function table all inherited the parent class, if the subclass to increase function, will continue to insert in the contiguous address, assuming that the extension function in the function table, also means that the subclasses also have, but children can’t no related record pointer function is the parent class method or a subclass, so don’t know the way where insert, The extension function cannot be safely placed in a subclass. So here we can side-prove that the methods in extension are called directly and belong only to the class, and are not inherited by subclasses.
Development notes:
- Methods and properties are inherited and cannot be written in Extension.
- A function created in an Extension must belong only to its own class, but its
Subclasses also have access
, justCannot inherit or override
.
Extensions: Final, @objc, dynamic modifier
The final modification
final
The way to decorate it isDirect dispatching
the
@ objc modification
- use
@objc
The keyword is willswift
Is exposed to OC,@objc
The way to decorate it isFunction table scheduling
. - OC will still not be able to call the swift method if you just use the @objc modifier, so if you want to
OC access swift
, class needs to be inheritedNSObject
. - A review of the SIL file reveals two @objc modified function declarations: swift+OC, which generates two methods in the SIL file
- The original swift function
- The @objc tag exposes functions to OC to use: those that call SWIFT internally
Using dynamic means that it can be modified dynamically, meaning that when you inherit from NSObject, you can use method-swizzling
Before functions in SWIFT that need to be swapped, use the dynamic modifier and then swap through: @_dynamicreplacement (for: function symbol), as shown below
class PDTeacher: NSObject { dynamic func teach(){ print("teach") } func teach2(){ print("teach2") } func teach3(){ print("teach3") } func teach4(){ print("teach4") } @objc deinit{} override init(){} } extension PDTeacher{ @_dynamicReplacement(for: teach) func teach5(){ print("teach5") } }Copy the code
Replace the teach method with teach5
conclusion
struct
isValue types
, where the scheduling of the function belongs toDirect call address
, i.e.,The static scheduling
.class
isReference types
Where the function is scheduled throughV - Table function Table
For scheduling, i.eDynamic scheduling
.extension
The function scheduling mode isDirect dispatching
.final
The function scheduling mode decorated isDirect dispatching
.@objc
The function schedule at any time isFunction table scheduling
If required in OC, class must also be usedInheritance NSObject
.dynamic
The scheduling mode of the modified function isFunction table scheduling
Is that the function is dynamic.@objc + dynamic
Combinatorial modified function scheduling is performed as isobjc_msgSend
Process, i.e.,Dynamic message forwarding
.