一、AFN和ASI的区别
ASI用cookies 保存在本地,不安全
AFN用session 保存服务器,相对安全
互坼锁,回到主线程
二、NSRunloop的五大类
一个线程至少有一个runloop
main的默认开启,子线程的默认关闭
1.RunloopRep
底层C的runloop
2.Model 相当于进程的状态
Default默认模式,Tracking用户交互模式,Common伪模式model集合,initialtialzation启动模式,eventRecei接受内部事件模式
3.Timer
等价于NSTimer
刷新有三种:GCD,NSTimer,CADisaplaytime Timer失效:1. Runloop 没有开启,2.runloop被释放了 Timer无法释放:重写调用方法,用虚类来引用父类进行消息转发 GCD依赖于系统内核,不会长生时差 NSTimer、CADisplayLink:到一定时间后,在进行消息转发,会存在一定的时差 GCD依赖于系统内核,自身不会有 NSTimer、CADisplayLink:会循环引用,需要结合NSProxy,进行消息转发 NSProxy:虚类,消息转发的代理,主要用于弱引用父类,实现消息转发的循环引用问题 多继承:将类名传入,再进行消息转发
4.Observer 监听线程状态
监听七种状态1.即将进入runloop 2.即将处理timer 3.即将处理source 4.即将sleep 5.刚被唤醒,即将退出sleep.6.即将退出exit 7.全部活动all activity
5.Source 0 互坼锁,1自旋锁
三、block
堆(有外部参数,只会拷贝值一次
栈(__block 将block拷贝到栈,从栈复制到堆并被block持有
全局 其他
NSInteger num = 3;
NSInteger(^block1)(NSInteger) = ^NSInteger(NSInteger n){
return n*num;
};
num = 1;
NSLog(@"%zd",block1(2));
//不加__block是6,加__block是2
NSInteger(^block3)(NSInteger) = ^NSInteger(NSInteger n){
return n*num;
};
NSLog(@"%zd",block3(2));
NSMutableArray * arr = [NSMutableArray arrayWithObjects:@"1",@"2", nil];
void(^block2)(void) = ^{
NSLog(@"%@",arr);//局部变量
[arr addObject:@"4"];
};
[arr addObject:@"3"];
arr = nil;
block2();
//不加__block是123,加__block是null
void(^block4)(void) = ^{
NSLog(@"%@",arr);//局部变量
[arr addObject:@"4"];
};
block4();
2021-01-08 14:06:05.895779+0800 SEEProxy[73093:2306879] 6
2021-01-08 14:06:05.896299+0800 SEEProxy[73093:2306879] 2
2021-01-08 14:06:05.896498+0800 SEEProxy[73093:2306879] (
1,
2,
3
)
2021-01-08 14:06:05.896623+0800 SEEProxy[73093:2306879] (null)
循环引用:weak
被释放:strong
四、离屏渲染:
触发: 1.使用了 mask 的 layer (layer.mask) 2.需要进行裁剪的 layer (layer.masksToBounds / view.clipsToBounds) 3.设置了组透明度为 YES,并且透明度不为 1 的 layer (layer.allowsGroupOpacity/ layer.opacity) 4.添加了投影的 layer (layer.shadow*) 5.采用了光栅化的 layer (layer.shouldRasterize) 6.绘制了文字的 layer (UILabel, CATextLayer, Core Text 等)
内存管理:
多线程:
线程锁:lock,@sythasy,
性能优化
一、Tableview
1.减少计算,缓存高度 2.减少线程等待,图片异常加载 3.复用机制,减少UI绘制 4.减少离屏渲染的使用,用图片代替圆角,阴影等
二、启动优化
1.减少动态库的使用 2.减少分类文件 3.减少+load函数的使用 4.减少C++静态对象 5.减少ObjC类 6.减少C的constructor函数
三、包瘦身
1.减少动态库的使用,framewoek,.a 2.图片压缩 3.本地化数据中,去掉不需存储的属性属性 4.定期删除缓存文件,图片、视频等
四、
冷启动与热启动
一、区别:
冷启动: 第一次打开app或app被杀死后重新打开叫冷启动(走didFinishLaunchWithOptions方法) 热启动 app在后台且存活的状态下,再次打开app叫热启动(不走didFinishLaunchWithOptions方法)
二、冷启动加载:
A、Premain T1:main()函数执行前
1.加载Math-O(系统可执行文件)到内存
2.加载 dyld(动态连接器)到内存
a.加载动态库:dyld 从主执行文件的 header 获取到需要加载的所依赖的动态库列表,然后找到每个 dylib,而 dylib 也可能依赖其他 dylib,所以这是一个递归加载依赖的过程
b.Rebase 和 Bind:
Rebase 在 Image 内部调整指针的指向。由于地址空间布局是随机的,需要在原来地址的基础上根据随机的偏移量做一下修正
Bind 把指针正确的指向 Image 外部的内容。这些指向外部的指针被符号绑定,dyld 需要去符号表里查找,找到 symbol 对应的实现
c.Objc setup:
1. 注册 Objc 类 2. 把 category 的定义插入方法列表 3. 保证每个 selector 唯一
d.Initializers:
1. Objc 的 +load 函数 2. C++ 构造函数属性函数 3. 非基本类型的 C++ 静态全局变量的创建(通常是类或结构体)
B、Aftermain T2:main()函数执行后到didFinishLaunchWithOptions
C、到用户看到主界面 T3:didFinishLaunchWithOptions到用户看到首页面
三、冷启动优化
- 动态库加载越多,启动越慢。
- ObjC类越多,启动越慢
- C的constructor函数越多,启动越慢
- C++静态对象越多,启动越慢
- ObjC的+load越多,启动越慢
TCP 三次握手,四次挥手
一、三次握手:
确保A听到B说话,B也听到A说话 A:听到我说话么 B:听到你说话,你听到我说话么 A:听到
二、四次挥手
确保A说完了,且B知道A说完了,B说完了,且A也知道B说完了 A:我说完了 B:我知道了,等一下,我可能还没说完 B:我也说完了 A:我知道了,结束吧