关于性能优化这块,我不喜欢长篇大论。根据个人经验,我主要总结了几点, 上篇主要讲解的是内存五大区和Tagger Pointer的简单应用。
要分清楚内存的几块区域,他们具备的特征,而不是记概念
官方文档地址: developer.apple.com/library/arc…
详细方法developer.apple.com 点击Document,进入后点击Documentation Archive
内存五大区:
栈区: 函数参数,局部变量压栈,高到低
堆区:alloc new, mrc需要手动释放,release堆上去的,低到高
BSS(全局区)(静态区),单例变量,static,常驻内存,程序退出后系统释放
常量区 profixheader中的宏,枚举,kvo,runtime常量等,常驻内存,程序退出后系统释放
程序代码区
栈: 压栈,从高到低 连续(每个int相差4个字节,指针8个字节) 栈地址 7开头的
堆: 堆起来, 从低到高,不连续(每个指针相差不是固定的8个字节),堆地址 6开头的
BSS,常量区 地址 10开头,非6 非7开头的
堆区的访问速度没有栈区快,因为要先从栈里面取出堆的地址,再取出值.
栈 &obj -> 堆 obj
` NSLog(@"%p", &obj);//0x7ffee5094c60 栈`
llvm中 x 0x00007ffee69ee960 会输出 00 80 0a 01 00 60 倒序后就是堆的地址 0x6000010a8000
po 0x6000010a8000 输出obj的值
也可以使用命令 可以对齐,不需要可以倒序打印
`NSLog(@"%p", obj1);//0x6000010a8000 堆`
大小不知道的可以,引入 #import <objc/runtime.h> 使用class_getInstanceSize(变量名)打印。
NSLog(@"%zd",class_getInstanceSize([obj class]));//8
补充:TagPointer: 概念省略
//// NSNumber* num = @(i); //0xf8f898a10947f44e 0xf8f898a10947f45e 前面是tag ,后面是Data
//// NSNumber* num = @(i*1.0f); //0xcc9af2369897bf6b 0xcc9af2369897bf7b 前面是tag ,后面是Data
// NSNumber* num = @(i*0xFFFFFFFFFFFFFFF); //0x6000002dc080 0x6000037c0000 6开头的话是堆上的
NSString* s = @"123";
NSString* s1 = [NSString stringWithFormat:@"123"];
NSString* s2 = [NSString stringWithFormat:@"12344556679"];
NSLog(@"s = %p \n s1 = %p \n s2 = %p \n", s, s1, s2);
// s = 0x1043ac068
// s1 = 0xc6f1371094ff4732
// s2 = 0x60000059d840 堆
Tagged Pointer专门用来存储小的对象,例如NSNumber和NSDate,此时它是真正的值,不再是一个对象,它的内存并不存储在堆中(地址不是6开头的,还需要从栈区找到堆地址,再根据地址取出值),也不需要malloc和free, 访问速度很快
判断是不是TaggedPointer 有个mask 1ul<<63,iOS真机判断地址最高位是否为1
关于散列表原理,weak原理,个人觉得没意义,对项目也没任何帮助,顶多就是了解一下哈希存储,不需要各位去写苹果底层,多此一举。