Swift底层原理-协议

2023-05-18  本文已影响0人  祀梦_

Swift底层原理-协议

协议的基本用法

协议的定义

protocol BaseProtocol {
    var x: Int {get set}
    var y: Double {get}
}

class TestClass: BaseProtocol {
    var x: Int = 0
    
    var y: Double = 0.0
}

协议中的属性

protocol BaseProtocol {
    var x: Int {get set}
    var y: Double {get}
}

class TestClass: BaseProtocol {
    // 可读写计算属性
    var x: Int {
        get {
            return 10
        }
        set {
            self.x = newValue
        }
    }
    
    // 可读计算属性
    var y: Double {
        get {
            return 20
        }
    }
}

class TestClass: BaseProtocol {
    // 变量存储属性,可读写
    var x: Int = 0
    
    // 变量存储属性,可读写
    var y: Double = 0.0
}

协议的方法

protocol BaseProtocol {
    func test()
}

类型方法

protocol BaseProtocol {
    static func test()
}

class TestClass: BaseProtocol {
    static func test() {
        print("test")
    }
}

异变方法

protocol BaseProtocol {
    mutating func test()
}

class TestClass: BaseProtocol {
    func test() {
        print("test")
    }
}

struct TestStruct: BaseProtocol {
    var x = 10
    mutating func test() {
        x = 20
    }
}

初始化方法

protocol BaseProtocol {
    init()
}

class TestClass: BaseProtocol {
    required init() {
        
    }
}
protocol BaseProtocol {
    init()
}

final class TestClass: BaseProtocol {
    init() {
        
    }
}

可选协议

@objc protocol BaseProtocol {
    @objc optional func test()
}
protocol BaseProtocol {
    func test()
}

extension BaseProtocol {
    func test() {
        
    }
}

协议的继承和组合

protocol BaseProtocol {
    func test()
}

protocol BaseProtocol1 {
    
}

class TestClass: BaseProtocol, BaseProtocol1 {
}
protocol BaseProtocol: AnyObject {}
protocol BaseProtocol: class {}

协议的底层原理

协议的方法调度

类实现协议

静态类型为类类型
protocol BaseProtocol {
    func test(_ number: Int)
}

class TestClass: BaseProtocol {
    var x: Int?
    func test(_ number: Int) {
        x = number
    }
}

var test: TestClass = TestClass()
test.test(10)

// main
sil [ossa] @main : $@convention(c) (Int32, UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>) -> Int32 {
bb0(%0 : $Int32, %1 : $UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>):
  alloc_global @$s4main4testAA9TestClassCvp       // id: %2
  %3 = global_addr @$s4main4testAA9TestClassCvp : $*TestClass // users: %8, %7
  %4 = metatype $@thick TestClass.Type            // user: %6
  // function_ref TestClass.__allocating_init()
  %5 = function_ref @$s4main9TestClassCACycfC : $@convention(method) (@thick TestClass.Type) -> @owned TestClass // user: %6
  %6 = apply %5(%4) : $@convention(method) (@thick TestClass.Type) -> @owned TestClass // user: %7
  store %6 to [init] %3 : $*TestClass             // id: %7
  %8 = begin_access [read] [dynamic] %3 : $*TestClass // users: %10, %9
  %9 = load [copy] %8 : $*TestClass               // users: %17, %16, %15
  end_access %8 : $*TestClass                     // id: %10
  %11 = integer_literal $Builtin.IntLiteral, 10   // user: %14
  %12 = metatype $@thin Int.Type                  // user: %14
  // function_ref Int.init(_builtinIntegerLiteral:)
  %13 = function_ref @$sSi22_builtinIntegerLiteralSiBI_tcfC : $@convention(method) (Builtin.IntLiteral, @thin Int.Type) -> Int // user: %14
  %14 = apply %13(%11, %12) : $@convention(method) (Builtin.IntLiteral, @thin Int.Type) -> Int // user: %16
  %15 = class_method %9 : $TestClass, #TestClass.test : (TestClass) -> (Int) -> (), $@convention(method) (Int, @guaranteed TestClass) -> () // user: %16
  %16 = apply %15(%14, %9) : $@convention(method) (Int, @guaranteed TestClass) -> ()
  destroy_value %9 : $TestClass                   // id: %17
  %18 = integer_literal $Builtin.Int32, 0         // user: %19
  %19 = struct $Int32 (%18 : $Builtin.Int32)      // user: %20
  return %19 : $Int32                             // id: %20
} // end sil function 'main'
sil_vtable TestClass {
  #TestClass.x!getter: (TestClass) -> () -> Int? : @$s4main9TestClassC1xSiSgvg  // TestClass.x.getter
  #TestClass.x!setter: (TestClass) -> (Int?) -> () : @$s4main9TestClassC1xSiSgvs    // TestClass.x.setter
  #TestClass.x!modify: (TestClass) -> () -> () : @$s4main9TestClassC1xSiSgvM    // TestClass.x.modify
  #TestClass.test: (TestClass) -> (Int) -> () : @$s4main9TestClassC4testyySiF   // TestClass.test(_:)
  #TestClass.init!allocator: (TestClass.Type) -> () -> TestClass : @$s4main9TestClassCACycfC    // TestClass.__allocating_init()
  #TestClass.deinit!deallocator: @$s4main9TestClassCfD  // TestClass.__deallocating_deinit
}
静态类型为协议类型
var test: BaseProtocol = TestClass()
// main
sil [ossa] @main : $@convention(c) (Int32, UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>) -> Int32 {
bb0(%0 : $Int32, %1 : $UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>):
  alloc_global @$s4main4testAA12BaseProtocol_pvp  // id: %2
  %3 = global_addr @$s4main4testAA12BaseProtocol_pvp : $*BaseProtocol // users: %9, %7
  %4 = metatype $@thick TestClass.Type            // user: %6
  // function_ref TestClass.__allocating_init()
  %5 = function_ref @$s4main9TestClassCACycfC : $@convention(method) (@thick TestClass.Type) -> @owned TestClass // user: %6
  %6 = apply %5(%4) : $@convention(method) (@thick TestClass.Type) -> @owned TestClass // user: %8
  %7 = init_existential_addr %3 : $*BaseProtocol, $TestClass // user: %8
  store %6 to [init] %7 : $*TestClass             // id: %8
  %9 = begin_access [read] [dynamic] %3 : $*BaseProtocol // users: %12, %11
  %10 = alloc_stack $BaseProtocol                 // users: %21, %20, %13, %11
  copy_addr %9 to [initialization] %10 : $*BaseProtocol // id: %11
  end_access %9 : $*BaseProtocol                  // id: %12
  %13 = open_existential_addr immutable_access %10 : $*BaseProtocol to $*@opened("39CCE43C-59EA-11ED-A979-86E79974171B") BaseProtocol // users: %19, %19, %18
  %14 = integer_literal $Builtin.IntLiteral, 10   // user: %17
  %15 = metatype $@thin Int.Type                  // user: %17
  // function_ref Int.init(_builtinIntegerLiteral:)
  %16 = function_ref @$sSi22_builtinIntegerLiteralSiBI_tcfC : $@convention(method) (Builtin.IntLiteral, @thin Int.Type) -> Int // user: %17
  %17 = apply %16(%14, %15) : $@convention(method) (Builtin.IntLiteral, @thin Int.Type) -> Int // user: %19
  %18 = witness_method $@opened("39CCE43C-59EA-11ED-A979-86E79974171B") BaseProtocol, #BaseProtocol.test : <Self where Self : BaseProtocol> (Self) -> (Int) -> (), %13 : $*@opened("39CCE43C-59EA-11ED-A979-86E79974171B") BaseProtocol : $@convention(witness_method: BaseProtocol) <τ_0_0 where τ_0_0 : BaseProtocol> (Int, @in_guaranteed τ_0_0) -> () // type-defs: %13; user: %19
  %19 = apply %18<@opened("39CCE43C-59EA-11ED-A979-86E79974171B") BaseProtocol>(%17, %13) : $@convention(witness_method: BaseProtocol) <τ_0_0 where τ_0_0 : BaseProtocol> (Int, @in_guaranteed τ_0_0) -> () // type-defs: %13
  destroy_addr %10 : $*BaseProtocol               // id: %20
  dealloc_stack %10 : $*BaseProtocol              // id: %21
  %22 = integer_literal $Builtin.Int32, 0         // user: %23
  %23 = struct $Int32 (%22 : $Builtin.Int32)      // user: %24
  return %23 : $Int32                             // id: %24
} // end sil function 'main'
sil_witness_table hidden TestClass: BaseProtocol module main {
  method #BaseProtocol.test: <Self where Self : BaseProtocol> (Self) -> (Int) -> () : @$s4main9TestClassCAA12BaseProtocolA2aDP4testyySiFTW  // protocol witness for BaseProtocol.test(_:) in conformance TestClass
}
// protocol witness for BaseProtocol.test(_:) in conformance TestClass
sil private [transparent] [thunk] [ossa] @$s4main9TestClassCAA12BaseProtocolA2aDP4testyySiFTW : $@convention(witness_method: BaseProtocol) (Int, @in_guaranteed TestClass) -> () {
// %0                                             // user: %4
// %1                                             // user: %2
bb0(%0 : $Int, %1 : $*TestClass):
  %2 = load_borrow %1 : $*TestClass               // users: %6, %4, %3
  %3 = class_method %2 : $TestClass, #TestClass.test : (TestClass) -> (Int) -> (), $@convention(method) (Int, @guaranteed TestClass) -> () // user: %4
  %4 = apply %3(%0, %2) : $@convention(method) (Int, @guaranteed TestClass) -> ()
  %5 = tuple ()                                   // user: %7
  end_borrow %2 : $TestClass                      // id: %6
  return %5 : $()                                 // id: %7
} // end sil function '$s4main9TestClassCAA12BaseProtocolA2aDP4testyySiFTW'

结构体实现协议

静态类型为结构体类型
protocol BaseProtocol {
    func test()
}

struct TestStruct: BaseProtocol {
    func test() {
    }
}

var test: TestStruct = TestStruct()
test.test()
// main
sil [ossa] @main : $@convention(c) (Int32, UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>) -> Int32 {
bb0(%0 : $Int32, %1 : $UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>):
  alloc_global @$s4main4testAA10TestStructVvp     // id: %2
  %3 = global_addr @$s4main4testAA10TestStructVvp : $*TestStruct // users: %8, %7
  %4 = metatype $@thin TestStruct.Type            // user: %6
  // function_ref TestStruct.init()
  %5 = function_ref @$s4main10TestStructVACycfC : $@convention(method) (@thin TestStruct.Type) -> TestStruct // user: %6
  %6 = apply %5(%4) : $@convention(method) (@thin TestStruct.Type) -> TestStruct // user: %7
  store %6 to [trivial] %3 : $*TestStruct         // id: %7
  %8 = begin_access [read] [dynamic] %3 : $*TestStruct // users: %10, %9
  %9 = load [trivial] %8 : $*TestStruct           // user: %12
  end_access %8 : $*TestStruct                    // id: %10
  // function_ref TestStruct.test()
  %11 = function_ref @$s4main10TestStructV4testyyF : $@convention(method) (TestStruct) -> () // user: %12
  %12 = apply %11(%9) : $@convention(method) (TestStruct) -> ()
  %13 = integer_literal $Builtin.Int32, 0         // user: %14
  %14 = struct $Int32 (%13 : $Builtin.Int32)      // user: %15
  return %14 : $Int32                             // id: %15
} // end sil function 'main'
静态类型为协议类型
var test: BaseProtocol = TestStruct()
// main
sil [ossa] @main : $@convention(c) (Int32, UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>) -> Int32 {
bb0(%0 : $Int32, %1 : $UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>):
  alloc_global @$s4main4testAA12BaseProtocol_pvp  // id: %2
  %3 = global_addr @$s4main4testAA12BaseProtocol_pvp : $*BaseProtocol // users: %9, %7
  %4 = metatype $@thin TestStruct.Type            // user: %6
  // function_ref TestStruct.init()
  %5 = function_ref @$s4main10TestStructVACycfC : $@convention(method) (@thin TestStruct.Type) -> TestStruct // user: %6
  %6 = apply %5(%4) : $@convention(method) (@thin TestStruct.Type) -> TestStruct // user: %8
  %7 = init_existential_addr %3 : $*BaseProtocol, $TestStruct // user: %8
  store %6 to [trivial] %7 : $*TestStruct         // id: %8
  %9 = begin_access [read] [dynamic] %3 : $*BaseProtocol // users: %12, %11
  %10 = alloc_stack $BaseProtocol                 // users: %17, %16, %13, %11
  copy_addr %9 to [initialization] %10 : $*BaseProtocol // id: %11
  end_access %9 : $*BaseProtocol                  // id: %12
  %13 = open_existential_addr immutable_access %10 : $*BaseProtocol to $*@opened("7CCB7D78-59EC-11ED-B59A-86E79974171B") BaseProtocol // users: %15, %15, %14
  %14 = witness_method $@opened("7CCB7D78-59EC-11ED-B59A-86E79974171B") BaseProtocol, #BaseProtocol.test : <Self where Self : BaseProtocol> (Self) -> () -> (), %13 : $*@opened("7CCB7D78-59EC-11ED-B59A-86E79974171B") BaseProtocol : $@convention(witness_method: BaseProtocol) <τ_0_0 where τ_0_0 : BaseProtocol> (@in_guaranteed τ_0_0) -> () // type-defs: %13; user: %15
  %15 = apply %14<@opened("7CCB7D78-59EC-11ED-B59A-86E79974171B") BaseProtocol>(%13) : $@convention(witness_method: BaseProtocol) <τ_0_0 where τ_0_0 : BaseProtocol> (@in_guaranteed τ_0_0) -> () // type-defs: %13
  destroy_addr %10 : $*BaseProtocol               // id: %16
  dealloc_stack %10 : $*BaseProtocol              // id: %17
  %18 = integer_literal $Builtin.Int32, 0         // user: %19
  %19 = struct $Int32 (%18 : $Builtin.Int32)      // user: %20
  return %19 : $Int32                             // id: %20
} // end sil function 'main'
// protocol witness for BaseProtocol.test() in conformance TestStruct
sil private [transparent] [thunk] [ossa] @$s4main10TestStructVAA12BaseProtocolA2aDP4testyyFTW : $@convention(witness_method: BaseProtocol) (@in_guaranteed TestStruct) -> () {
// %0                                             // user: %1
bb0(%0 : $*TestStruct):
  %1 = load [trivial] %0 : $*TestStruct           // user: %3
  // function_ref TestStruct.test()
  %2 = function_ref @$s4main10TestStructV4testyyF : $@convention(method) (TestStruct) -> () // user: %3
  %3 = apply %2(%1) : $@convention(method) (TestStruct) -> ()
  %4 = tuple ()                                   // user: %5
  return %4 : $()                                 // id: %5
} // end sil function '$s4main10TestStructVAA12BaseProtocolA2aDP4testyyFTW'

extention中提供方法的默认实现

协议中未声明方法,分类中声明并实现

protocol BaseProtocol {
    
}

extension BaseProtocol {
    func test() {
        print("BaseProtocol")
    }
}

class TestClass: BaseProtocol {
    func test() {
        print("TestClass")
    }
}

var test: BaseProtocol = TestClass()
test.test()

var test1: TestClass = TestClass()
test1.test()

打印结果:

BaseProtocol

TestClass

// main
sil [ossa] @main : $@convention(c) (Int32, UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>) -> Int32 {
bb0(%0 : $Int32, %1 : $UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>):
  alloc_global @$s4main4testAA12BaseProtocol_pvp  // id: %2
  %3 = global_addr @$s4main4testAA12BaseProtocol_pvp : $*BaseProtocol // users: %9, %7
  %4 = metatype $@thick TestClass.Type            // user: %6
  // function_ref TestClass.__allocating_init()
  %5 = function_ref @$s4main9TestClassCACycfC : $@convention(method) (@thick TestClass.Type) -> @owned TestClass // user: %6
  %6 = apply %5(%4) : $@convention(method) (@thick TestClass.Type) -> @owned TestClass // user: %8
  %7 = init_existential_addr %3 : $*BaseProtocol, $TestClass // user: %8
  store %6 to [init] %7 : $*TestClass             // id: %8
  %9 = begin_access [read] [dynamic] %3 : $*BaseProtocol // users: %12, %11
  %10 = alloc_stack $BaseProtocol                 // users: %17, %16, %13, %11
  copy_addr %9 to [initialization] %10 : $*BaseProtocol // id: %11
  end_access %9 : $*BaseProtocol                  // id: %12
  %13 = open_existential_addr immutable_access %10 : $*BaseProtocol to $*@opened("A1E0E9E8-59EE-11ED-8487-86E79974171B") BaseProtocol // users: %15, %15
  // function_ref BaseProtocol.test()
  %14 = function_ref @$s4main12BaseProtocolPAAE4testyyF : $@convention(method) <τ_0_0 where τ_0_0 : BaseProtocol> (@in_guaranteed τ_0_0) -> () // user: %15
  %15 = apply %14<@opened("A1E0E9E8-59EE-11ED-8487-86E79974171B") BaseProtocol>(%13) : $@convention(method) <τ_0_0 where τ_0_0 : BaseProtocol> (@in_guaranteed τ_0_0) -> () // type-defs: %13
  destroy_addr %10 : $*BaseProtocol               // id: %16
  dealloc_stack %10 : $*BaseProtocol              // id: %17
  alloc_global @$s4main5test1AA9TestClassCvp      // id: %18
  %19 = global_addr @$s4main5test1AA9TestClassCvp : $*TestClass // users: %24, %23
  %20 = metatype $@thick TestClass.Type           // user: %22
  // function_ref TestClass.__allocating_init()
  %21 = function_ref @$s4main9TestClassCACycfC : $@convention(method) (@thick TestClass.Type) -> @owned TestClass // user: %22
  %22 = apply %21(%20) : $@convention(method) (@thick TestClass.Type) -> @owned TestClass // user: %23
  store %22 to [init] %19 : $*TestClass           // id: %23
  %24 = begin_access [read] [dynamic] %19 : $*TestClass // users: %26, %25
  %25 = load [copy] %24 : $*TestClass             // users: %29, %28, %27
  end_access %24 : $*TestClass                    // id: %26
  %27 = class_method %25 : $TestClass, #TestClass.test : (TestClass) -> () -> (), $@convention(method) (@guaranteed TestClass) -> () // user: %28
  %28 = apply %27(%25) : $@convention(method) (@guaranteed TestClass) -> ()
  destroy_value %25 : $TestClass                  // id: %29
  %30 = integer_literal $Builtin.Int32, 0         // user: %31
  %31 = struct $Int32 (%30 : $Builtin.Int32)      // user: %32
  return %31 : $Int32                             // id: %32
} // end sil function 'main'

协议中声明方法,分类中实现

protocol BaseProtocol {
    func test()
}

extension BaseProtocol {
    func test() {
        print("BaseProtocol")
    }
}

class TestClass: BaseProtocol {
    func test() {
        print("TestClass")
    }
}

var test: BaseProtocol = TestClass()
test.test()

var test1: TestClass = TestClass()
test1.test()

打印结果:

TestClass

TestClass

协议的结构

protocol BaseProtocol {
    func test()
}

extension BaseProtocol {
    func test() {
    }
}

class TestClass: BaseProtocol {
    var x: Int = 10
    func test() {
        
    }
}


var test: BaseProtocol = TestClass()

var test1: TestClass = TestClass()

print("test size: \(MemoryLayout.size(ofValue: test))")
print("test1 size: \(MemoryLayout.size(ofValue: test1))")

打印结果:

test size: 40

test1 size: 8

[图片上传失败...(image-a9fb64-1684500471316)]

[图片上传失败...(image-8e3b77-1684500471316)]

witness_table的结构

define i32 @main(i32 %0, i8** %1) #0 {
entry:
  %2 = bitcast i8** %1 to i8*
  // 获取TestClass的metadata
  %3 = call swiftcc %swift.metadata_response @"type metadata accessor for main.TestClass"(i64 0) #7
  %4 = extractvalue %swift.metadata_response %3, 0
  // %swift.type = type { i64 }
  // %swift.refcounted = type { %swift.type*, i64 }
  // %T4main9TestClassC = type <{ %swift.refcounted, %TSd }>
  // 创建Test实例
  %5 = call swiftcc %T4main9TestClassC* @"main.TestClass.__allocating_init() -> main.TestClass"(%swift.type* swiftself %4)
  
  // %T4main12BaseProtocolP = type { [24 x i8], %swift.type*, i8** },%T4main12BaseProtocolP 本质上是一个结构体
  // 注意看,getelementptr为获取结构体成员,i32 0 结构体的内存地址,拿到这个结构体后将 %4 存储到这个结构体的第二个成员变量上
  // 也就是将 metadata 存储到这个结构体的第二个成员变量上,此时这个结构体的结构为:{ [24 x i8], metadata, i8** }
  store %swift.type* %4, %swift.type** getelementptr inbounds (%T4main12BaseProtocolP, %T4main12BaseProtocolP* @"main.test : main.BaseProtocol", i32 0, i32 1), align 8

  // 这一行在获取 witness table,然后将 witness table 存储到 %T4main12BaseProtocolP 这个结构体的第三个成员变量上(因为取的是 i32 2)
  // 此时 %T4main5ShapeP 的结构为:{ [24 x i8], metadata, witness_table }
  store i8** getelementptr inbounds ([2 x i8*], [2 x i8*]* @"protocol witness table for main.TestClass : main.BaseProtocol in main", i32 0, i32 0), i8*** getelementptr inbounds (%T4main12BaseProtocolP, %T4main12BaseProtocolP* @"main.test : main.BaseProtocol", i32 0, i32 2), align 8
  
  // [24 x i8] 是 24 个 Int8 数组,内存中等价 [3 x i64] 数组,等价于 %T4main5ShapeP = type { [3 x i64], %swift.type*, i8** }
  // 这里是将 %T4main5ShapeP 这个结构体强制转换成 %T4main9TestClassC,此时的结构为:{ [3 x i64], metadata, witness_table }
  // 然后把 %5 存放到 %T4main12BaseProtocolP 的第一个元素。所以最后的结构为:{ [%T4main9TestClassC*, i64, i64], metadata, witness_table },    
  store %T4main9TestClassC* %5, %T4main9TestClassC** bitcast (%T4main12BaseProtocolP* @"main.test : main.BaseProtocol" to %T4main9TestClassC**), align 8
  ret i32 0
}
@"protocol witness table for main.TestClass : main.BaseProtocol in main" = hidden constant [2 x i8*] 
    [i8* bitcast (%swift.protocol_conformance_descriptor* @"protocol conformance descriptor for main.TestClass : main.BaseProtocol in main" to i8*), 
    i8* bitcast (void (%T4main9TestClassC**, %swift.type*, i8**)* @"protocol witness for main.BaseProtocol.test() -> () in conformance main.TestClass : main.BaseProtocol in main" to i8*)], 
    align 8
template <typename Runtime>
class TargetWitnessTable {
  /// The protocol conformance descriptor from which this witness table
  /// was generated.
  ConstTargetMetadataPointer<Runtime, TargetProtocolConformanceDescriptor>
    Description;

public:
  const TargetProtocolConformanceDescriptor<Runtime> *getDescription() const {
    return Description;
  }
};
template <typename Runtime>
struct TargetProtocolConformanceDescriptor final
  : public swift::ABI::TrailingObjects<
             TargetProtocolConformanceDescriptor<Runtime>,
             TargetRelativeContextPointer<Runtime>,
             TargetGenericRequirementDescriptor<Runtime>,
             TargetResilientWitnessesHeader<Runtime>,
             TargetResilientWitness<Runtime>,
             TargetGenericWitnessTable<Runtime>> {
    // 省略部分方法

private:
  /// The protocol being conformed to.
  TargetRelativeContextPointer<Runtime, TargetProtocolDescriptor> Protocol;
  
  // Some description of the type that conforms to the protocol.
  TargetTypeReference<Runtime> TypeRef;

  /// The witness table pattern, which may also serve as the witness table.
  RelativeDirectPointer<const TargetWitnessTable<Runtime>> WitnessTablePattern;

  /// Various flags, including the kind of conformance.
  ConformanceFlags Flags;
}
template<typename Runtime>
struct TargetProtocolDescriptor final
    : TargetContextDescriptor<Runtime>,
      swift::ABI::TrailingObjects<
        TargetProtocolDescriptor<Runtime>,
        TargetGenericRequirementDescriptor<Runtime>,
        TargetProtocolRequirement<Runtime>>
{
  // 省略部分方法
private:
  /// The name of the protocol.
  TargetRelativeDirectPointer<Runtime, const char, /*nullable*/ false> Name;

  /// The number of generic requirements in the requirement signature of the
  /// protocol.
  uint32_t NumRequirementsInSignature;

  /// The number of requirements in the protocol.
  /// If any requirements beyond MinimumWitnessTableSizeInWords are present
  /// in the witness table template, they will be not be overwritten with
  /// defaults.
  uint32_t NumRequirements;

  /// Associated type names, as a space-separated list in the same order
  /// as the requirements.
  RelativeDirectPointer<const char, /*Nullable=*/true> AssociatedTypeNames;

  // 省略部分方法
}

Existential Container-存在容器

上一篇 下一篇

猜你喜欢

热点阅读