美文网首页
01-OC对象本质

01-OC对象本质

作者: weyan | 来源:发表于2019-03-11 13:12 被阅读0次

一、面向对象

苹果的开源网站:https://opensource.apple.com/tarballs/

image.png

1.内存对齐:结构体的最终大小必须是最大成员大小的倍数
2.一个OC对象,系统至少分配16字节
3.系统为对象分配内存时是16倍数


sizeof()是运算符,不是函数,在编译时就确定占用多少内存空间,而class_getInstanceSize()和malloc_size()是在程序运行过程中根据参数确定内存空间

二、OC对象的分类

1、instance对象

2、Class对象

3、meta-class对象


总结:
  • Class object_getClass(id obj): (runtime的api)
    1、如果传入参数的是实例(instance)对象,那么返回的是类(Class)对象
    2、如果传入的参数是类(Class)对象,那么返回的是元类(meta-class)对象
    3、如果传入的参数是元类(meta-class)对象,那么返回的是基类(NSObject)的元类(meta-class)对象
  • Class objc_getClass(const char *aClassName): (runtime的api)
    传入的参数是字符串类名:如果找到给字符串对应的类就返回类对象,找不到的话就返回nil
  • -(Class)class 和 +(Class)class
    1、返回类对象

三、isa指针

1、验证instance对象的isa指针指向的是Class对象

2、验证Class对象的isa指向的是元类对象

四、superclass指针

1、类对象的superclass指针

2、元类对象的superclass指针

总结:

证明 证明

总结:OC的方法调用时不知道调用的是类方法或者对象方法,只知道给某个对象发送消息

五、Class的结构

验证类对象和元类对象struct objc_class 结构,存储的bits信息(方法信息、属性信息、协议信息)

代码如下:

------------------------MJClassInfo.h-----------------------
#import <Foundation/Foundation.h>

#ifndef MJClassInfo_h
#define MJClassInfo_h

# if __arm64__
#   define ISA_MASK        0x0000000ffffffff8ULL
# elif __x86_64__
#   define ISA_MASK        0x00007ffffffffff8ULL
# endif

#if __LP64__
typedef uint32_t mask_t;
#else
typedef uint16_t mask_t;
#endif
typedef uintptr_t cache_key_t;

struct bucket_t {
    cache_key_t _key;
    IMP _imp;
};

struct cache_t {
    bucket_t *_buckets;
    mask_t _mask;
    mask_t _occupied;
};

struct entsize_list_tt {
    uint32_t entsizeAndFlags;
    uint32_t count;
};

struct method_t {
    SEL name;
    const char *types;
    IMP imp;
};

struct method_list_t : entsize_list_tt {
    method_t first;
};

struct ivar_t {
    int32_t *offset;
    const char *name;
    const char *type;
    uint32_t alignment_raw;
    uint32_t size;
};

struct ivar_list_t : entsize_list_tt {
    ivar_t first;
};

struct property_t {
    const char *name;
    const char *attributes;
};

struct property_list_t : entsize_list_tt {
    property_t first;
};

struct chained_property_list {
    chained_property_list *next;
    uint32_t count;
    property_t list[0];
};

typedef uintptr_t protocol_ref_t;
struct protocol_list_t {
    uintptr_t count;
    protocol_ref_t list[0];
};

struct class_ro_t {
    uint32_t flags;
    uint32_t instanceStart;
    uint32_t instanceSize;  // instance对象占用的内存空间
#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;
};

struct class_rw_t {
    uint32_t flags;
    uint32_t version;
    const class_ro_t *ro;
    method_list_t * methods;    // 方法列表
    property_list_t *properties;    // 属性列表
    const protocol_list_t * protocols;  // 协议列表
    Class firstSubclass;
    Class nextSiblingClass;
    char *demangledName;
};

#define FAST_DATA_MASK          0x00007ffffffffff8UL
struct class_data_bits_t {
    uintptr_t bits;
public:
    class_rw_t* data() {
        return (class_rw_t *)(bits & FAST_DATA_MASK);
    }
};

/* OC对象 */
struct mj_objc_object {
    void *isa;
};

/* 类对象 */
struct mj_objc_class : mj_objc_object {
    Class superclass;
    cache_t cache;
    class_data_bits_t bits;
public:
    class_rw_t* data() {
        return bits.data();
    }
    
    mj_objc_class* metaClass() {
        return (mj_objc_class *)((long long)isa & ISA_MASK);
    }
};

#endif /* MJClassInfo_h */
----------------------main.mm---------------------
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
#import "MJClassInfo.h"

// MJPerson
@interface MJPerson : NSObject <NSCopying>
{
@public
    int _age;
}
@property (nonatomic, assign) int no;
- (void)personInstanceMethod;
+ (void)personClassMethod;
@end

@implementation MJPerson

- (void)test
{
    
}

- (void)personInstanceMethod
{
    
}
+ (void)personClassMethod
{
    
}
- (id)copyWithZone:(NSZone *)zone
{
    return nil;
}
@end

// MJStudent
@interface MJStudent : MJPerson <NSCoding>
{
@public
    int _weight;
}
@property (nonatomic, assign) int height;
- (void)studentInstanceMethod;
+ (void)studentClassMethod;
@end

@implementation MJStudent
- (void)test
{
    
}
- (void)studentInstanceMethod
{
    
}
+ (void)studentClassMethod
{
    
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
    return nil;
}

- (void)encodeWithCoder:(NSCoder *)aCoder
{
    
}
@end


int main(int argc, const char * argv[]) {
    @autoreleasepool {
        MJStudent *stu = [[MJStudent alloc] init];
        stu->_weight = 10;
        
        mj_objc_class *studentClass = (__bridge mj_objc_class *)([MJStudent class]);
        mj_objc_class *personClass = (__bridge mj_objc_class *)([MJPerson class]);
        
        class_rw_t *studentClassData = studentClass->data();
        class_rw_t *personClassData = personClass->data();
        
        class_rw_t *studentMetaClassData = studentClass->metaClass()->data();
        class_rw_t *personMetaClassData = personClass->metaClass()->data();

        NSLog(@"1111");
    }
    return 0;
}

面试题

相关文章

  • 01-OC对象本质

    一、面向对象 苹果的开源网站:https://opensource.apple.com/tarballs/ 1.内...

  • 01-OC对象的本质

    OC对象的本质 我们平时编写的OC代码,最终转换为底层实现基本上绝大部分都是基于C\C++来实现的 下面展示OC代...

  • 01-OC对象的本质

    OC是通过C/C++的什么数据结构实现我们的OC对象呢 结构体--OC对象的本质就是C/C++的结构体 Class...

  • 01-OC对象的本质

    一个NSObject对象占用多少内存?系统分配了16个字节给NSObject对象(通过malloc_size函数获...

  • 01-OC对象的本质

    探究:1.objc_alloc流程2.init操作3.开辟内存 alloc开辟内存. objc_alloc流程1....

  • OC底层原理探索文档汇总

    OC底层探索: 01-OC对象的底层分析[https://www.jianshu.com/p/953fcfddde...

  • OC 与 Swift

    OC对象的本质(上):OC对象的底层实现原理OC对象的本质(中):OC对象的种类OC对象的本质(下):详解isa&...

  • OC对象的本质(中)—— OC对象的种类

    OC对象的本质(上):OC对象的底层实现原理OC对象的本质(中):OC对象的种类OC对象的本质(下):详解isa&...

  • OC对象的本质(下)—— 详解isa&supercl

    OC对象的本质(上):OC对象的底层实现原理OC对象的本质(中):OC对象的种类OC对象的本质(下):详解isa&...

  • OC对象原理探究(下)

    介绍正文前,我们思考一个问题,什么是对象?或者说OC对象的本质是什么? 对象本质以及拓展 在探索oc对象本质前,先...

网友评论

      本文标题:01-OC对象本质

      本文链接:https://www.haomeiwen.com/subject/ihtiqqtx.html