OC 底层原理笔记

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

2018-11-15  本文已影响0人  zysmoon
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++的什么数据结构实现的?
答:结构体

xcrun  -sdk  iphoneos  clang  -arch  arm64  -rewrite-objc  OC源文件  -o  输出的CPP文件
如果需要链接其他框架,使用-framework参数。比如-framework UIKit

2. 一个OC对象在内存中是如何布局的?
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 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

上一篇 下一篇

猜你喜欢

热点阅读