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的类的内存布局
#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对象占用多少内存空间?
- 代码实现如下
#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.png2个容易混淆的函数
- 创建一个实例对象,至少需要多少内存?
#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的教程视频
非常感谢.
网友评论