iOS底层系列09 -- isa的底层探索

2021-02-10  本文已影响0人  YanZi_33

OC对象在C/C++底层的本质

@interface YYPerson : NSObject

@property(nonatomic,copy)NSString *name;

@end
@interface YYStudent : YYPerson

@property(nonatomic,assign)NSInteger age;

@end
Snip20210209_114.png Snip20210209_115.png Snip20210209_116.png Snip20210209_118.png

isa的结构分析

inline void objc_object::initIsa(Class cls, bool nonpointer, bool hasCxxDtor) 
{ 
    ASSERT(!isTaggedPointer()); 
    
    if (!nonpointer) {
        isa = isa_t((uintptr_t)cls);
    } else {
        ASSERT(!DisableNonpointerIsa);
        ASSERT(!cls->instancesRequireRawIsa());

        //创建一个isa_t对象
        isa_t newisa(0);

#if SUPPORT_INDEXED_ISA
        ASSERT(cls->classArrayIndex() > 0);
        newisa.bits = ISA_INDEX_MAGIC_VALUE;
        // isa.magic is part of ISA_MAGIC_VALUE
        // isa.nonpointer is part of ISA_MAGIC_VALUE
        newisa.has_cxx_dtor = hasCxxDtor;
        //isa_t属性与class的绑定关系建立
        newisa.indexcls = (uintptr_t)cls->classArrayIndex();
#else
        newisa.bits = ISA_MAGIC_VALUE;
        // isa.magic is part of ISA_MAGIC_VALUE
        // isa.nonpointer is part of ISA_MAGIC_VALUE
        newisa.has_cxx_dtor = hasCxxDtor;
        newisa.shiftcls = (uintptr_t)cls >> 3;
#endif
        // This write must be performed in a single store in some cases
        // (for example when realizing a class because other threads
        // may simultaneously try to use the class).
        // fixme use atomics here to guarantee single-store and to
        // guarantee memory order w.r.t. the class index table
        // ...but not too atomic because we don't want to hurt instantiation
        //将创建isa_t赋值给对象的isa属性,实现了对象isa的初始化,即实现了对象与class的绑定
        isa = newisa;
    }
}
Snip20210209_119.png Snip20210209_120.png Snip20210209_121.png Snip20210210_122.png Snip20210210_123.png Snip20210210_127.png Snip20210210_130.png Snip20210210_132.png Snip20210210_135.png
Class object_getClass(id obj)
{
    if (obj) return obj->getIsa();
    else return Nil;
}
objc_object::getIsa() 
{
    if (fastpath(!isTaggedPointer())) return ISA();

    extern objc_class OBJC_CLASS_$___NSUnrecognizedTaggedPointer;
    uintptr_t slot, ptr = (uintptr_t)this;
    Class cls;

    slot = (ptr >> _OBJC_TAG_SLOT_SHIFT) & _OBJC_TAG_SLOT_MASK;
    cls = objc_tag_classes[slot];
    if (slowpath(cls == (Class)&OBJC_CLASS_$___NSUnrecognizedTaggedPointer)) {
        slot = (ptr >> _OBJC_TAG_EXT_SLOT_SHIFT) & _OBJC_TAG_EXT_SLOT_MASK;
        cls = objc_tag_ext_classes[slot];
    }
    return cls;
}
inline Class 
objc_object::ISA() 
{
    ASSERT(!isTaggedPointer()); 
#if SUPPORT_INDEXED_ISA
    if (isa.nonpointer) {
        uintptr_t slot = isa.indexcls;
        return classForIndex((unsigned)slot);
    }
    return (Class)isa.bits;
#else
    return (Class)(isa.bits & ISA_MASK);
#endif
}

自定义实现系统的ISA指针类型 -- 位域

第一个版本
#import <Foundation/Foundation.h>

@interface YYPerson : NSObject

@property(nonatomic,assign)BOOL tall;
@property(nonatomic,assign)BOOL rich;
@property(nonatomic,assign)BOOL handsome;

@end
#import "YYPerson.h"

#define YYTallMask (1<<0)
#define YYRichMask (1<<1)
#define YYHandsomeMask (1<<2)

@interface YYPerson ()
{
    char _tallRichHandsome;
}
//0000 0001
//倒数第一位  表示tall
//倒数第二位  表示rich
//倒数第三位  表示handsome
@end

@implementation YYPerson

- (instancetype)init{
    self = [super init];
    if (self) {
        _tallRichHandsome = 0b00000011;
    }
    return self;
}

- (void)setTall:(BOOL)tall{
    if (tall) {
        _tallRichHandsome |= YYTallMask;
    }else{
        _tallRichHandsome &= ~YYTallMask;
    }
}

- (BOOL)tall{
    return !!(_tallRichHandsome & YYTallMask);
}

- (void)setRich:(BOOL)rich{
    if (rich) {
        _tallRichHandsome |= YYRichMask;
    }else{
        _tallRichHandsome &= ~YYRichMask;
    }
}

- (BOOL)rich{
    return !!(_tallRichHandsome & YYRichMask);
}

- (void)setHandsome:(BOOL)handsome{
    if (handsome) {
        _tallRichHandsome |= YYHandsomeMask;
    }else{
        _tallRichHandsome &= ~YYHandsomeMask;
    }
}

- (BOOL)handsome{
    return !!(_tallRichHandsome & YYHandsomeMask);
}
@end
#import <Foundation/Foundation.h>
#import "YYPerson.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        
        YYPerson *person = [[YYPerson alloc]init];
        
        NSLog(@" tall = %d -- rich = %d -- handsome =  %d",person.tall,person.rich,person.handsome);
        
        person.handsome = YES;
        
        NSLog(@" tall = %d -- rich = %d -- handsome =  %d",person.tall,person.rich,person.handsome);
    }
    return 0;
}
Snip20210629_19.png
第二个版本
#import "YYPerson.h"

@interface YYPerson ()
{
    //结构体 + 位域
    struct{
        char tall : 1;
        char rich : 1;
        char handsome : 1;
    }_tallRichHandsome;
}
@end

@implementation YYPerson

- (instancetype)init{
    self = [super init];
    if (self) {
        
    }
    return self;
}

- (void)setTall:(BOOL)tall{
    _tallRichHandsome.tall = tall;
}

- (BOOL)tall{
    return !!_tallRichHandsome.tall;
}

- (void)setRich:(BOOL)rich{
    _tallRichHandsome.rich = rich;
}

- (BOOL)rich{
    return !!_tallRichHandsome.rich;
}

- (void)setHandsome:(BOOL)handsome{
    _tallRichHandsome.handsome = handsome;
}

- (BOOL)handsome{
    return !!_tallRichHandsome.handsome;
}
@end
#import <Foundation/Foundation.h>
#import "YYPerson.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        
        YYPerson *person = [[YYPerson alloc]init];
        person.tall = YES;
        person.rich = NO;
        person.handsome = NO;
        
        NSLog(@" tall = %d -- rich = %d -- handsome =  %d",person.tall,person.rich,person.handsome);
    }
    return 0;
}
Snip20210629_20.png
第三个版本
#import <Foundation/Foundation.h>

@interface YYPerson : NSObject

- (void)setTall:(BOOL)tall;
- (BOOL)tall;

- (void)setRich:(BOOL)rich;
- (BOOL)rich;

- (void)setHandsome:(BOOL)handsome;
- (BOOL)handsome;

@end
#define YYTallMask (1<<0)
#define YYRichMask (1<<1)
#define YYHandsomeMask (1<<2)

#import "YYPerson.h"

@interface YYPerson ()
{
    //共用体
    union{
        char bits;
        struct{
            char tall : 1;
            char rich : 1;
            char handsome : 1;
        };
    }_tallRichHandsome;
}
//0000 0001
//倒数第一位  表示tall
//倒数第二位  表示rich
//倒数第三位  表示handsome
@end

@implementation YYPerson

- (instancetype)init{
    self = [super init];
    if (self) {
        
    }
    return self;
}

- (void)setTall:(BOOL)tall{
    if (tall) {
        _tallRichHandsome.bits |= YYTallMask;
    }else{
        _tallRichHandsome.bits &= ~YYTallMask;
    }
    
}

- (BOOL)tall{
    return !!(_tallRichHandsome.bits & YYTallMask);
}

- (void)setRich:(BOOL)rich{
    if (rich) {
        _tallRichHandsome.bits |= YYRichMask;
    }else{
        _tallRichHandsome.bits &= ~YYRichMask;
    }
}

- (BOOL)rich{
    return !!(_tallRichHandsome.bits & YYRichMask);
}

- (void)setHandsome:(BOOL)handsome{
    if (handsome) {
        _tallRichHandsome.bits |= YYHandsomeMask;
    }else{
        _tallRichHandsome.bits &= ~YYHandsomeMask;
    }
}

- (BOOL)handsome{
    return !!(_tallRichHandsome.bits & YYHandsomeMask);
}
@end
#import <Foundation/Foundation.h>
#import "YYPerson.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        
        YYPerson *person = [[YYPerson alloc]init];
        person.tall = YES;
        person.rich = NO;
        person.handsome = NO;
        
        NSLog(@" tall = %d -- rich = %d -- handsome =  %d",person.tall,person.rich,person.handsome);
    }
    return 0;
}
Snip20210629_21.png
上一篇下一篇

猜你喜欢

热点阅读