iOS-底层原理(1)-对象的本质

Objective-C的本质

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

image.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的底层实现
iOS-底层原理(1)-对象的本质_第1张图片
image.png
  • 继承自NSObject的类的内存布局
iOS-底层原理(1)-对象的本质_第2张图片
image.png
iOS-底层原理(1)-对象的本质_第3张图片
image.png
#import 
#import 
#import 

// 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;
}

打印结果

iOS-底层原理(1)-对象的本质_第4张图片
image.png
  • 思考:一个Person对象、一个Student对象占用多少内存空间?
iOS-底层原理(1)-对象的本质_第5张图片
image.png
  • 代码实现如下
#import 
#import 
#import 

// 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;
}

运行结果


iOS-底层原理(1)-对象的本质_第6张图片
image.png

2个容易混淆的函数

  • 创建一个实例对象,至少需要多少内存?
#import 
class_getInstanceSize([NSObject class]);
  • 创建一个实例对象,实际上分配了多少内存?
#import 
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字节

本文参考借鉴MJ的教程视频,非常感谢.


项目连接地址 - Interview_OC

你可能感兴趣的:(iOS-底层原理(1)-对象的本质)