preface

Take time to read this article in the busy friends, I hope you can read this question can harvest. This article is mainly to share with you is the Swift structure and class method scheduling. Well, without further ado, let’s get straight to the point.

1. Common method is the difference between the two methods scheduling

● Common methods in a class are scheduled in the way of function distribution. ○ Detailed analysis will come later: General method exposition of method schedulingCopy the code

2. Discuss the difference between the two methods in scheduling

○ Class: Method scheduling is all function scheduling ● Protocol type declaration, regardless of whether the protocol implementation is a class or a structure: ○ If a method is first defined in the protocol itself, it is scheduled in the protocol function table. ○ If a method is first defined in the protocol extension, it is scheduled in the static dispatch mode

3. The impact of Extension on method scheduling in classes

``extension PersonClass {

    ``func changClassName10``() {}

}

SIL code:

Breakpoint, assembler trace:

You can see that the changClassName10 method, when executed, is modified by function_ref, which is not in the list of functions in the sil_vtable. The address of the function is determined at compile time; at run time, it is executed directly. So the extended method is static distribution.

🤔**** think: why is a normal function in an extension, it is not in the function table, not the way the function is dispatched?

In [Ordinary Methods for Method scheduling: I will post ordinary method calls later] : a function table is an array structure in which functions are arranged in order.

If the parent class has extension methods in the function table, you need to consider the order in which it and its subclass methods are arranged. Which comes first depends on the order in which the files are compiled. If the subclass compiles first and the superclass compiles later, all the methods of the subclass are shifted in order, and the extended method is inserted after the superclass method. This will make compilation less efficient. The extension method uses static distribution, which is a method of exchanging space for time. Methods in extension protocols are also statically distributed, they are the same thing.

 

[note] class extension method, need to note:

  • A subclass may not override a method defined by its parent class
  • Cannot exist/override methods of the same name that already exist in an inheritance link in an extension

4. The effect of modifiers on class method scheduling

1. Access modifiers modify methods

private func changClassName2``() {}

fileprivate func changClassName3``() {}

public func changClassName4``() {}

internal func changClassName5``() {}

open func changClassName6``() {}

SIL code: sil_vtable SIL

Although all the methods that function modifiers modify exist in the function table, it is obviousPrivate modified changClassName2, andFileprivate modifies changClassName3Unusual, they come after the method namein _12232F587A4C5CD8B1EEDF696793A4FC* * * *. How does this difference make them different from other access modifiers in method scheduling?Now look at method scheduling SIL:

You can findPrivate modified changClassName2, andFileprivate modifies changClassName3When called, the preceding modifier is specified byfunction_refmodified.Rather thanclass_methodModification. So it isStatic distribution?

Assembler debugging again:

The address of the function is determined at compile time; at run time, it is executed directly. So the private/ Fileprivate access modifier modifies static distribution.

The function table contains functions in a class that may be dynamically distributed for execution.

 

Summary:

The private/ Fileprivate access modifier modifies static distribution.

The public/open/internal access modifiers modify function distribution.

 

2. @objc modifiers: function tables

@objc func changClassName7 ‘ ‘() {} vtable SIL:

Method scheduling SIL:

Run, assemble:

So: calling the @objc modifier in Swift is function dispatch. nothing special.

So what does @objc do?

 

Let’s look at the changClassName7 method defined in SIL code:

As you can see, in addition to the normal definition of the changClassName7 method, an additional layer is generated@objc main.PersonClass.changClassName7()This method internally calls the normally defined changClassName7.

So this method is exposed to the interface method called in OC. No @objc modifier is available in OC.

3. The function table is dynamic

Dynamic func changClassName8 ‘ ‘() {} vtable SIL:

Method scheduling SIL:

Run, assemble:

At compile time, the address of the method cannot be determined in the function table, so Dynamic method scheduling mode It’s function distribution.

 

So what does dynamic do?

Look at the method definition SIL:

Unlike normal functions, there is an extra one when the method is defineddynamically_replacableThe label indicates that this is aDynamic methods can be replaced. Fungible means fungible in the case of method interchange at OC runtime.

If you want to swap Swift methods, you need to add the dynamic modifier to the replaced method.

Use @_dynamicreplacement (for: teach) to complete the replacement.

Example code is as follows:

““class PersonClassNSObject {`

    ``dynamic func teach``() {

        ``print``(``"teach"``)

` `}

}

 

extension PersonClass {

// The method exchange provided in SWIFT 5

// Replace the teach method with the Teach1 method below this line

// implement the teach method, which actually implements the Teach1 method

    ``@``_dynamicReplacement``(``for``: ``teach``)

    ``func teach1``() {

        ``print``(``"teach1"``)

` `}

}

let t = ``PersonClass``()

t.teach()

So it prints: “Teach1”

4. @objc dynamic: message forwarding

The source code is as follows:

1 @objc dynamic func changClassName9``() {}

vtable SIL:

There are no changClassName9 functions in the function table.

 

Method scheduling SIL:

Unlike normal functions, which distribute method calls, not as class_method, isobjc_methodway

 

Running, assembly debugging:

Assembly debugging, see the familiarobjc_msgSend . This is the OC’s way of forwarding messages for method scheduling.

5. The static modifier

Static modified methods, called class methods, can be called directly from the class name without creating instance objects.

The source code is as follows:

1 static func changClassName11``() {}

vtable SIL:

Method scheduling SIL:

Running, assembly debugging:

Get the function in function_ref, so it is statically distributed

6. The final modification

A few rules for using the final modifier

  • The final modifier can only modify a class, indicating that the class cannot be inherited by other classes, that is, it does not qualify as a parent class.
  • The final modifier can also modify a method ina class, indicating that the method cannot be overridden by subclasses.
  • Final cannot modify structures, enumerations, or protocols.

The source code is as follows:

1 final func changClassName1``() {}

table SIL:

Method scheduling SIL:

Line and assembly debugging:

Get the function in function_ref, so it is statically distributed

5. To summarize

Functions in a function table are not necessarily scheduled in the way that functions are distributed. But if it’s not in the function table, it’s definitely not the way the function is distributed.

The method of scheduling can be judged by how the function is retrieved at call time. Here are the different scheduling methods corresponding to different methods of getting functions:

Method scheduling in Swift can be divided into two categories: dynamic scheduling and static scheduling

  • Direct (static scheduling) : Retrieves functions as function_ref in an SIL file
    • Common method of 🌰 structure
    • The modifiers for methods ina class are final/private/fileprivate/static
    • Classes, structs, and methods within protocol extensions
  • The Dynamic Dispatch ( Dynamic scheduling ) : ☞ Official document portal Dynamic Dispatch
    • Table (function Table scheduling) : Retrieves functions from Vtable in SIL file as class_method
    • 🌰 methods in ordinary classes
    • The modifiers for the methods in the class are: open/public/internal / @objc/dynamaic
    • Message (Message forwarding scheduling) : In the SIL file, get the function as objc_method
    • 🌰 @ objc dynamaic
    • Witness_method (protocol table scheduling) : Obtain the witness_method function through the PWT in the SIL file
    • 🌰 a structure or class that complies with the protocol and implements the methods defined by the protocol itself

Ok, xiaobian to arrange the swift structure and class method scheduling, if there is a harvest, point a thumb-up!

Green mountains do not change, green water flow, see you soon, thank every beautiful woman for her support!

Swift Information:Download address

From: Address