iOS性能优化(上)

625 阅读3分钟

关于性能优化这块,我不喜欢长篇大论。根据个人经验,我主要总结了几点, 上篇主要讲解的是内存五大区和Tagger Pointer的简单应用。

要分清楚内存的几块区域,他们具备的特征,而不是记概念

官方文档地址: developer.apple.com/library/arc…

详细方法developer.apple.com 点击Document,进入后点击Documentation Archive

23457799-ed5058a4e15962a5.png

内存五大区:

栈区: 函数参数,局部变量压栈,高到低

堆区:alloc new, mrc需要手动释放,release堆上去的,低到高

BSS(全局区)(静态区),单例变量,static,常驻内存,程序退出后系统释放

常量区 profixheader中的宏,枚举,kvo,runtime常量等,常驻内存,程序退出后系统释放

程序代码区

23457799-daa14f58361b3bcc.png

23457799-d6e6e91e5f4fd97a.png

栈: 压栈,从高到低 连续(每个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: 概念省略

image.png

image.png

////            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原理,个人觉得没意义,对项目也没任何帮助,顶多就是了解一下哈希存储,不需要各位去写苹果底层,多此一举。