1.我们平时编写的Objective-C代码,底层实现其实都是C\C++代码
a) 所以Objective- C的面向对象都是基于C\C++ 的数据结构实现的
2.Objective-C的对象类主要是基于C\C++的什么数据结构实现的?
a) 结构体
3.将Objective-C代码转换为C\C++代码
a) clang - rewrite- objc main. m - o main. cpp
b) 建议不要按照该上面的方式转换, 编辑器将OC代码转成C++ 代码 依赖如下:
1 ) 什么平台的代码
2 ) 不同平台支持的代码肯定是不一样的( Windows、Mac、iOS)
3 ) 最终C++ 代码是要转成汇编的,汇编代码是严重依赖硬件的( 模拟器( i386) 、32 bit ( armv7) 、64 bit ( arm64) )
4 ) 如果需要链接其他框架,使用- framework参数。比如- framework UIKit
c) xcrun - sdk iphoneos clang - arch arm64 - rewrite- objc OC源文件 - o 输出的CPP文件
NSObject * obj = [ [ NSObject alloc] init] ;
那么对于对上面代码的解读就变成了这个指针所指向的内存存储空间有多大?
a) 系统分配了16 个字节给NSObject对象( 通过malloc_size函数获得)
b) 但NSObject对象只使用了8 个字节的空间( 64 bit环境下, 可通过class_getInstanceSize函数获得)
a) NSObject的底层实现
@interface NSObject {
Class isa;
} ;
@end
struct NSObject_IMPL {
Class isa;
} ;
b) Class是什么呢?
1 ) typedef struct objc_class * Class;
2 ) isa在内存中的地址就是结构体的地址
c) 那么指针所占所少内存?
8 个字节( 64 bit) / 4 个字节( 32 bit)
d)
class_getInstanceSize ( [ NSObject class] )
e)
malloc_size ( ( __bridge const void * ) obj)
a) OC底层实现开源地址
b) CoreFoundation内部规定最少分配16 个字节
c) 可通过Xcode自带的工具Debug -- > Debug Workflow -- > View Memory ( Shift+ Command+ M)
读取数据的方式,牵扯到大端 / 小端 iOS是小端模式,会从高地址开始读取,地址值比较大的地方
d) 也可以通过LLDB ( 动态调试器) 指令
p : print ( 打印)
po : print object ( 打印对象)
memory read : 读取内存
x/ 数量、格式、字节数 内存地址
格式:
x是16 进制,f是浮点,d是10 进制
字节大小:
b:byte 1 字节,h:half word 2 字节
w:word 4 字节,g:giant word 8 字节
memory write: 修改内存中的值( memory write 内存地址 数值)
e) 1 个16 进制位代表4 个2 进制位, 2 个16 进制位代表8 个2 进制位, 即一个字节
a) 创建一个实例对象,至少需要多少内存?
# import < objc/ runtime. h>
class_getInstanceSize ( [ NSObject class] ) ;
b) 创建一个实例对象,实际分配了多少内存?
# import < malloc/ malloc. h>
malloc_size ( ( __bridge const void * ) obj) ;
8.一个Person对象,一个Student对象占用多少内存空间?
a) Person底层的实现
struct NSObject_IMPL {
Class isa;
}
struct Person_IMPL {
struct NSObject_IMPL NSObject_IVARS;
int _age;
}
struct Student_IMPL {
struct Person_IMPL Person_IVARS;
int _no;
}
b) Student底层的实现
struct NSObject_IMPL {
Class isa;
}
struct Student_IMPL {
struct NSObject_IMPL NSObject_IVARS;
int _no;
int _age;
}
== >
struct Student_IMPL {
Class isa;
int _no;
int _age;
}
c) 那么stu的地址值是那个呢?
1 ) 结构体首元素的地址值: 0x100400110
就像数组的地址值就是数组首元素的地址值
d) 将stu指针转成底层实现的指针形式
1 ) struct Student_IMPL * stuImpl = ( __bridge struct Student_IMPL * ) stu;
再通过结构体指针去访问成员变量
NSLog ( @"no is %d, age is %d" , stuImpl-> _no, stuImpl-> _age) ;
a) 成员变量
1 ) @interface Person : NSObject
{
int _age;
}
b) 属性
1 ) @property ( nonatomic, assign) int height;
c) 多加一条属性的内存大小
1 ) struct Person_IMPL {
struct NSObject_IMPL NSObject_IVARS;
int _age;
int _height;
int _no;
}
2 ) sizeOf == > 24
3 ) class_getInstanceSize == > 24
4 ) mallocSize == > 32
5 ) 总结: 我只需要24 ,但是实际返回了32 ,mallocSize实际调用calloc,结论:操作系统分配内存的时候也有对齐的概念,他会分配好,方便cpu更好的访问和管理Buckets size分配好,堆空间的内存管理,nano的分配方式最大1 块是256 ,在iOS里面他返回的都是16 的倍数;
6 ) gnu的全称是gnu not unix not unix 开源组织