美文网首页OC 底层原理笔记
1 OC使用原理 - 1-OC 对象的本质

1 OC使用原理 - 1-OC 对象的本质

作者: zysmoon | 来源:发表于2018-11-15 13:40 被阅读0次
    Objective-C的本质

    我们平时编写的Objective-C代码,底层实现其实都是C\C++代码

    1653926-277b9ac165d4083c.png

    将OC代码翻译成C++代码,我们可以看到

    // NSObject Implementation
    struct NSObject_IMPL {
        Class isa; // 8个字节
    };
    // 指针
    // typedef struct objc_class *Class;
    
    

    所以Objective-C的面向对象都是基于C\C++的数据结构实现的

    Objective-C的对象、类主要是基于C\C++的什么数据结构实现的?
    答:结构体

    • 将Objective-C代码转换为C\C++代码
    xcrun  -sdk  iphoneos  clang  -arch  arm64  -rewrite-objc  OC源文件  -o  输出的CPP文件
    如果需要链接其他框架,使用-framework参数。比如-framework UIKit
    
    
    2. 一个OC对象在内存中是如何布局的?
    • NSObject的底层实现


      1653926-d67459a5d3d8c70c.png
    • 继承自NSObject的类的内存布局
    1653926-058c1c80a9065a28.png 1653926-e5ba718a988fe53d.png
    #import <Foundation/Foundation.h>
    #import <objc/runtime.h>
    #import <malloc/malloc.h>
    
    // NSObject Implementation
    struct NSObject_IMPL {
        Class isa; // 8个字节
    };
    // 指针 - typedef struct objc_class *Class;
    
    struct Student_IMPL {
        struct NSObject_IMPL NSObject_IVARS;    // 8个字节
        int _no;    // 4
        int _age;   // 4
    };  // 16个字节,内存对齐,结构体的大小必须是最大成员大小的倍数
    
    // Person
    @interface Student: NSObject {
        @public
        int _no;
        int _age;
    }
    @end
    
    @implementation Student
    
    
    @end
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            NSObject *obj = [[NSObject alloc] init];
    
            // 获得NSObject实例对象的成员变量所占用的大小 >> 8
            NSLog(@"%zd",class_getInstanceSize([NSObject class]));
    
            // 获得obj指针所指向内存的大小 >> 16
            NSLog(@"%zd",malloc_size((__bridge const void *)obj));
    
            Student *stu = [[Student alloc] init];
            NSLog(@"stu - %zd",class_getInstanceSize([Student class]));
            NSLog(@"stu - %zd",malloc_size((__bridge const void *)stu));
        }
        return 0;
    }
    
    

    打印结果

    1653926-fec1a285a16f6941.png
    • 思考:一个Person对象、一个Student对象占用多少内存空间?
    1653926-78e9a1e8db85c1c2.png
    • 代码实现如下
    #import <Foundation/Foundation.h>
    #import <objc/runtime.h>
    #import <malloc/malloc.h>
    
    // NSObject Implementation
    struct NSObject_IMPL {
        Class isa; // 8个字节
    };
    // 指针 - typedef struct objc_class *Class;
    
    struct Person_IMPL {
        struct NSObject_IMPL NSObject_IVARS;    // 8个字节
        int _age;   // 4
    };  // 16个字节,内存对齐,结构体的大小必须是最大成员大小的倍数
    
    // Person
    @interface Person: NSObject {
        int _age;
    }
    @end
    
    @implementation Person
    
    @end
    
    // Person
    @interface Student: Person {
        int _no;
    }
    @end
    
    @implementation Student
    
    @end
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            NSObject *obj = [[NSObject alloc] init];
    
            // 获得NSObject实例对象的成员变量所占用的大小 >> 8
            NSLog(@"%zd",class_getInstanceSize([NSObject class]));
    
            // 获得obj指针所指向内存的大小 >> 16
            NSLog(@"%zd",malloc_size((__bridge const void *)obj));
    
            Person *person = [[Person alloc] init];
            NSLog(@"Person - %zd",class_getInstanceSize([Person class]));
            NSLog(@"Person - %zd",malloc_size((__bridge const void *)person));
    
            Student *stu = [[Student alloc] init];
            NSLog(@"stu - %zd",class_getInstanceSize([Student class]));
            NSLog(@"stu - %zd",malloc_size((__bridge const void *)stu));
        }
        return 0;
    }
    
    

    运行结果

    1653926-a9cc99579f3ae28f.png

    2个容易混淆的函数

    • 创建一个实例对象,至少需要多少内存?
    #import <objc/runtime.h>
    class_getInstanceSize([NSObject class]);
    
    
    • 创建一个实例对象,实际上分配了多少内存?
    #import <malloc/malloc.h>
    malloc_size((__bridge const void *)obj);
    
    

    2.常用LLDB指令

    • 打印
    print、p:打印
    po:打印对象
    
    
    • 读取内存
    memory read/数量格式字节数  内存地址
    x/数量格式字节数  内存地址
    x/3xw  0x10010
    
    
    • 修改内存中的值
    memory  write  内存地址  数值
    memory  write  0x0000010  10
    
    
    • 格式
    x是16进制,f是浮点,d是10进制
    
    
    • 字节大小
    b:byte 1字节,h:half word 2字节
    w:word 4字节,g:giant word 8字节
    
    

    本文参考:
    路飞_Luck (https://www.jianshu.com/p/07f7b96bb03f)
    以及借鉴MJ的教程视频
    非常感谢.


    项目连接地址 - Interview_OC

    相关文章

      网友评论

        本文标题:1 OC使用原理 - 1-OC 对象的本质

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