重学OC第四篇:类结构之bits

前言

在上一篇中已经知道类的结构体为

struct objc_class : objc_object {
   
    // Class ISA;
    Class superclass;
    cache_t cache;             // formerly cache pointer and vtable
    class_data_bits_t bits;    // class_rw_t * plus custom rr/alloc flags
    ......
}

第一个存放的isa,第二个存放的父类,第三个从字面理解是缓存,第四个从上面的注释可以得知,bits里主要的信息就是class_rw_t *加上一些自定义rr/alloc标记。
那么方法、属性、成员变量等信息存在了哪里?

一、bits有什么?方法?属性?成员变量?

1 class_data_bits_t

struct class_data_bits_t {
   
    friend objc_class;

    // Values are the FAST_ flags above.
    uintptr_t bits;
    ......
    class_rw_t* data() const {
   
        return (class_rw_t *)(bits & FAST_DATA_MASK);
    }
    void setData(class_rw_t *newData)
    {
   
        ASSERT(!data()  ||  (newData->flags & (RW_REALIZING | RW_FUTURE)));
        // Set during realization or construction only. No locking needed.
        // Use a store-release fence because there may be concurrent
        // readers of data and data's contents.
        uintptr_t newBits = (bits & ~FAST_DATA_MASK) | (uintptr_t)newData;
        atomic_thread_fence(memory_order_release);
        bits = newBits;
    }

    // Get the class's ro data, even in the presence of concurrent realization.
    // fixme this isn't really safe without a compiler barrier at least
    // and probably a memory barrier when realizeClass changes the data field
    const class_ro_t *safe_ro() {
   
        class_rw_t *maybe_rw = data();
        if (maybe_rw->flags & RW_REALIZED) {
   
            // maybe_rw is rw
            return maybe_rw->ro();
        } else {
   
            // maybe_rw is actually ro
            return (class_ro_t *)maybe_rw;
        }
    }
    .......
}

通过friend关键字把objc_class设为了友元结构体,从而可以访问其私有内容。
class_data_bits_t中只有一个bits变量,从注释中得知里面存着以FAST_开头的定义的flags,例如FAST_HAS_DEFAULT_RR、FAST_CACHE_HAS_CXX_DTOR等等。class_data_bits_t结构体里并没有看到方法、属性相关的内容,但是通过data()方法可以看到bits变量中还存有一个class_rw_t类型的data指针。

2 class_rw_t


struct class_rw_t {
   
 	......
    const method_array_t methods() const {
   
        auto v = get_ro_or_rwe();
        if (v.is<class_rw_ext_t *>()) {
   
            return v.get<class_rw_ext_t *>()->methods;
        } else {
   
            return method_array_t{
   v.get<const class_ro_t *>()->baseMethods()};
        }
    }

    const property_array_t properties() const {
   
        auto v = get_ro_or_rwe();
        if (v.is<class_rw_ext_t *>()) {
   
            return v.get<class_rw_ext_t *>()->properties;
        } else {
   
            return property_array_t{
   v.get<const class_ro_t *>()->baseProperties};
        }
    }

    const protocol_array_t protocols() const {
   
        auto v = get_ro_or_rwe();
        if (v.is<class_rw_ext_t *>()) {
   
            return v.get<class_rw_ext_t *>()->protocols;
        } else {
   
            return protocol_array_t{
   v.get<const class_ro_t *>()->baseProtocols};
        }
    }
};

在class_rw_t结构体中我们找到了methods()、properties()、protocols()方法,从methods()方法体中看到它有两种返回情况,一种是class_rw_ext_t,一种是class_ro_t。

2.1 class_rw_ext_t

struct class_rw_ext_t {
   
    const class_ro_t *ro;			//存放的就是ro的内容
    method_array_t methods;			//存放ro中的方法+动态添加的方法
    property_array_t properties;    
    protocol_array_t protocols;    
    char *demangledName;
    uint32_t version;     //元类7,非元类0
};

2.2 class_ro_t

struct class_ro_t {
   
    uint32_t flags;
    uint32_t instanceStart;
    uint32_t instanceSize;
#ifdef __LP64__
    uint32_t reserved;
#endif

    const uint8_t * ivarLayout;
    
    const char * name;
    method_list_t * baseMethodList;
    protocol_list_t * baseProtocols;
    const ivar_list_t * ivars;

    const uint8_t * weakIvarLayout;
    property_list_t *baseProperties;

    // This field exists only when RO_HAS_SWIFT_INITIALIZER is set.
    _objc_swiftMetadataInitializer __ptrauth_objc_method_list_imp _swiftMetadataInitializer_NEVER_USE[0];

    _objc_swiftMetadataInitializer swiftMetadataInitializer() const {
   
        if (flags & RO_HAS_SWIFT_INITIALIZER) {
   
            return _swiftMetadataInitializer_NEVER_USE[0];
        } else {
   
            return nil;
        }
    }

    method_list_t *baseMethods() const {
   
        return baseMethodList;
    }

    class_ro_t *duplicate() const {
   
        if (flags & RO_HAS_SWIFT_INITIALIZER) {
   
            size_t size = sizeof(*this) + sizeof(_swiftMetadataInitializer_NEVER_USE[0]);
            class_ro_t *ro = (class_ro_t *)memdup(this, size);
            ro->_swiftMetadataInitializer_NEVER_USE[0] = this->_swiftMetadataInitializer_NEVER_USE[0];
            return ro;
        } else {
   
            size_t size = sizeof(*this);
            class_ro_t *ro = (class_ro_t *)memdup(this, size);
            return ro;
        }
    }
};

可以在这里面看到有baseMethodList、ivars、baseProperties等信息,那么方法、成员变量、属性到底存没存在这些地方?如果是存在这些地方,class_rw_ext_t和class_ro_t中存的方法、属性、协议信息又有什么区别?我们通过代码去验证一下。

二、验证

@interface TestA : NSObject

@property(nonatomic, copy) NSString *nickname;

- (void)sayHello;
+ (void)sayAny;

@end

@implementation TestA

- (void)sayHello {
   
    
}

+ (void)sayAny {
   
    
}

@end

@interface TestA(SayU)

- (void)sayU;

@end

@implementation TestA(SayU)

- (void)sayU {
   
    
}

@end

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值