Swift 属性底层整理

101 阅读5分钟

一、存储属性

  • 定义:存储属性是一个作为特定类和结构体实例一部分的常量或变量。存储属性要么是变量存储属性(var 引入)或者是常量存储属性(let 引入)。枚举enum不可定义
/// 存储属性

    let kp: Int

    var pk: String

    init(_ kp: Int, _ pk: String) {

        self.kp = kp

        self.pk = pk

    }

    

    var origin: Point = Point()

    var size: Size = Size()

    ///  计算属性、

    ///  必须var申明

    ///  属性的类型不可忽略

    ///  要修改属性的值,必须实现setter,否则只要getter

    var pointer: Point {

        get {

            let pointx = origin.x + size.width

            let pointy = origin.y + size.height

            return Point(x: pointx, y: pointy)

        }

        /// 修改值

        set(newPointer) {

            origin.x = newPointer.x - size.width

            origin.y = newPointer.y - size.height

        }

    }

    

    /// 类型属性

    static var allWidth: Double = 0

image.png 占用空间MemoryLayout<Circle>.stride打印为8。说计算属性没用占内存

二、计算属性

  • 定义:不直接存储值,而是通过get set 方法来取值或者赋值,同时还可以对其他属性进行操作。本质是方法函数

三、类型属性

  • 定义:定义在类上的属性,用static来修饰属性。

四、延迟属性

  • 定义: 在第一次使用时初始化。lazy

五、属性观察者

  • 定义:用来观察属性值的变化,willset当属性被调用这个值相同,而didset属性已经变化后调用。类似于set get。只有在完全初始化的实例分配新值的时候才会调用

属性在的位置

struct TargetClassMetadata {

    /// The address point of instances of this type.  此类型实例的地址点

    var InstanceAddressPoint: Int32

    /// The required size of instances of this type. 此类型实例的所需大小。

      /// 'InstanceAddressPoint' bytes go before the address point; 字节位于地址点之前

      /// 'InstanceSize - InstanceAddressPoint' bytes go after it. 字节位于其后面

    var InstanceSize: Int32

    /// The alignment mask of the address point of instances of this type. 此类型实例的地址点的对齐掩码

    var InstanceAlignMask: Int32

    /// Reserved for runtime use.  保留供运行时使用

    var Reserved: Int32

    /// The total size of the class object, including prefix and suffix

    /// extents.  类对象的总大小,包括前缀和后缀范围。

    var ClassSize: Int32

    /// The offset of the address point within the class object. 类对象内地址点的偏移量。

    var ClassAddressPoint: Int32

    /// An out-of-line Swift-specific description of the type, or null

      /// if this is an artificial subclass.  We currently provide no

      /// supported mechanism for making a non-artificial subclass

      /// dynamically.

    var typeDescriptor: UnsafeMutableRawPointer ///  ->  v_table

    ////// A function for destroying instance variables, used to clean up after an

    /// early return from a constructor. If null, no clean up will be performed

    /// and all ivars must be trivial.

    var iVarDescroyer: UnsafeRawPointer

}

struct Metadata {

    /// The kind. Only valid for non-class metadata; getKind() must be used to get

    ///  kind 仅对非类元数据有效;必须使用getKind()来获取值。

    /// the kind value.

    var kind: Int

    

    var superClass: Any.Type

    var cacheData: (Int, Int)

    var data: Int

    var classFlags: Int32

    /// start TargetClassMetadata

    var instanceAddressPoint: UInt32

    var instanceSize: UInt32

    var instanceAligmentMask: UInt16

    var reserver: UInt16

    var classSize: UInt32

    var classAdressPoint: UInt32

    var typeDescriptor: UnsafeMutableRawPointer ///  ->  v_table  TargetTypeContextDescriptor

    var iVarDescroyer: UnsafeRawPointer

    /// end TargetClassMetadata

}

struct TargetTypeContextDescriptor {

    /// The name of the type.  类型的名称。

    var name: UInt32

    /// A pointer to the metadata access function for this type.指向此类型的元数据访问函数的指针。

    ///

    /// The function type here is a stand-in. You should use getAccessFunction() 这里的函数类型是一个替代。您应该使用getAccessFunction()

    /// to wrap the function pointer in an accessor that uses the proper calling 将函数指针包装在使用正确调用的访问器中

    /// convention for a given number of arguments. 给定数量的参数的约定。

    var accessFunctionPointer: Int32

    /// A pointer to the field descriptor for the type, if any. 指向类型的字段描述符(如果有)的指针。 属性信息

    var FieldDescriptor: Int32

}

/// TargetClassDescriptor 包含 TargetTypeContextDescriptor

struct TargetClassDescriptor {

    var flags: UInt32

    var parent: UInt32

    var name: UInt32

    var accessFunctionPointer: Int32

    var FieldDescriptor: Int32

//    var targetTypeContextDescriptor: TargetTypeContextDescriptor

    /// The type of the superclass, expressed as a mangled type name that can 超类的类型,表示为可以

    /// refer to the generic arguments of the subclass type. 请参阅子类类型的泛型参数。

    var SuperclassType: Int32

    /// If this descriptor does not have a resilient superclass, this is the 如果此描述符没有弹性超类,则为 此类元数据对象的负大小(大写)。

    /// negative size of metadata objects of this class (in words).

    var MetadataNegativeSizeInWords: UInt32

    /// If this descriptor does not have a resilient superclass, this is the 如果此描述符没有弹性超类,则为此类元数据对象的正大小(大写)。

    /// positive size of metadata objects of this class (in words).

    var MetadataPositiveSizeInWords: UInt32

    /// The number of additional members added by this class to the class 此类添加到该类的其他成员数,元数据。默认情况下,此数据对运行时是不透明的,而不是在其他成员中暴露;真的只是数据的nummediatemembers*sizeof(void*)字节。

      /// metadata.  This data is opaque by default to the runtime, other than

      /// as exposed in other members; it's really just

      /// NumImmediateMembers * sizeof(void*) bytes of data.

      ///这些字节是在地址点之前还是之后添加的 取决于areImmediateMembersNegative()

      /// Whether those bytes are added before or after the address point

      /// depends on areImmediateMembersNegative().

    var NumImmediateMembers: UInt32  // ABI: could be uint16_t?

    

    /// The number of stored properties in the class, not including its 类中存储的属性数,不包括其超级类。如果存在场偏移向量,则这是其长度。

    /// superclasses. If there is a field offset vector, this is its length.

    var NumFields: UInt32

\


    /// The offset of the field offset vector for this class's stored 此类存储的字段的字段偏移向量的偏移量

     /// properties in its metadata, in words. 0 means there is no field offset 属性在其元数据中,以文字表示。0表示没有字段偏移

     /// vector.

     ///

     /// If this class has a resilient superclass, this offset is relative to 如果该类具有弹性超类,则该偏移量相对于弹性超类元数据的大小。否则就是

     /// the size of the resilient superclass metadata. Otherwise, it is

     /// absolute.

    var FieldOffsetVectorOffset: UInt32

    

    var offset: UInt32

    var size: UInt32

    // V-Table

}

\


// Field descriptors contain a collection of field records for a single

// class, struct or enum declaration.

//字段描述符包含单个字段的字段记录集合

//类、结构或枚举声明。

struct FieldDescriptor {

    var MangledTypeName: Int32

    var Superclass: Int32

    var kind: Int32

    var FieldRecordSize: Int32

    var NumFields: Int32 /// 代表有多少属性,

    var FieldRecords: [FieldRecord] /// 每个属性的信息

//    const FieldRecord *getFieldRecordBuffer() const {

//        return reinterpret_cast<const FieldRecord *>(this + 1);

//      }

}

struct FieldRecord{

    var Flags: Int32

    var MangledTypeName: Int32

    var FieldName: Int32

}