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 fileSee it in SILv-table, as shown in the figure below

According to the figure above,

  • sil_vtableKey words:
  • LGTeacher: Indicates yesLGTeacherA 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 understandAn array of, the statement inInside the classIn the process without any keyword modification,Continuous depositIn our currentAddress spaceIn 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 itsSubclasses also have access, justCannot inherit or override.

Extensions: Final, @objc, dynamic modifier

The final modification

  • finalThe way to decorate it isDirect dispatchingthe

@ objc modification

  • use@objcThe keyword is willswiftIs exposed to OC,@objcThe 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 toOC 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

  • structisValue types, where the scheduling of the function belongs toDirect call address, i.e.,The static scheduling.
  • classisReference typesWhere the function is scheduled throughV - Table function TableFor scheduling, i.eDynamic scheduling.
  • extensionThe function scheduling mode isDirect dispatching.
  • finalThe function scheduling mode decorated isDirect dispatching.
  • @objcThe function schedule at any time isFunction table schedulingIf required in OC, class must also be usedInheritance NSObject.
  • dynamicThe scheduling mode of the modified function isFunction table schedulingIs that the function is dynamic.
  • @objc + dynamicCombinatorial modified function scheduling is performed as isobjc_msgSendProcess, i.e.,Dynamic message forwarding.