1、系统UI事件传递机制
流程:
UI事件传递机制- 倒序遍历子视图,最后添加到UIWindow上的视图会最先被遍历到
2、UIView和CALayer关系
- UIView负责事件传递和视图响应
- CALyer负责内容显示
- 体现单一职责原则
3、tableview卡顿优化
CPU相关:
- 对象创建,对象销毁等放到子线程
- 预排版---文本计算、UI布局计算等放到子线程处理
- 预渲染---文本等异步绘制、图片等异步解码等
GPU相关
- 避免触发离屏渲染---圆角、阴影、蒙层等
- 视图混合---降低图层复杂度
4、UI绘制原理
UI绘制系统绘制流程:
系统绘制流程5、离屏渲染
1. 如何理解离屏渲染?
- 离屏渲染指的是GPU在当前屏幕缓冲区以外新开辟一个缓冲区进行渲染操作
- 当我们指定了UI视图的某些属性,标记为它在未预合成之前不能用于当前屏幕直接显示就会触发离屏渲染
2.何时触发离屏渲染?
- 设置圆角,并且设置maskToBounds = YES
- 图层蒙版
- 阴影
- 光栅化
3.为何要避免离屏渲染?
- 触发离屏渲染会增加GPU工作量,概率会导致 CPU+GPU工作耗时超出16.7(1/60秒)毫秒,进而导致UI卡顿和掉帧
6、分类
1.分类可以做什么?
- 声明私有方法
- 分解体积庞大的类文件
- 把framework的私有方法公开
2.分类特点?
- 运行时决议
- 可以为系统类添加分类
3.分类中可以添加哪些内容?
- 实例方法
- 添加类方法
- 协议
- 属性---只增加get和set方法,没有添加实例变量
4.注意事项
- 分类添加的方法可以“覆盖”原类方法
- 同名分类方法谁能生效取决于编译顺序,最后被编译的分类它会优先生效
- 名字相同的分类会引起编译报错
7、关联对象
本质
- 关联对象由AssociationsManager管理并在AssocitionsHashMap存储
- 所有对象的关联内容都在同一个全局容器中
8、扩展
1.扩展可以做什么?
- 声明私有属性
- 声明私有方法
- 声明私有成员变量
2.分类和扩展的区别?
- 编译时决议
- 只以申明的形式存在,多数情况下寄生于宿主类的.m中
- 不能为系统类添加扩展
9、代理
- 代理是一种设计模式
- iOS中@protocol形式体现
- 一对一传递
-
工作流程:
代理
10、通知
1.特点
- 使用观察者模式来实现的,用于跨层传递消息的机制。
- 传递方式为一对多。
2.通知流程
通知流程3.猜测通知的实现机制?
- 通知中心(NotificationCenter)维护一个map表,存放通知名(notificationName)对应观察者列表(ObserversList)
11、KVO
- KVO是key value observing 的缩写
- KVO是OC对观察者模式的又一实现
- Apple使用isa混写(isa-swizzling)来实现KVO
实现原理:
- 当被观察者A被添加观察者后(addObserver),系统会创建一个被观察者A的子类 NSKVOnotifying_A,并通过isa混写技术(isa-sawizzling),将A的isa指针指向新的类,新子类重写setter方法:
- (void)setValue:(id)obj {
[self willChangeValueForKey:@"keyPath"];
[super setValue:obj];
[self willChangeValueForKey:@"keyPath"];
}
KVO实现原理
1.通过KVC设置value,KVO能否生效?为什么?
- 能生效
- KVC会调用setter方法触发KVO生效
2.通过成员变量直接赋值value,KVO能否生效?
- 不会生效,可通过手动添加 willChangeValueForKey 和 willChangeValueForKey方法使其生效
12、KVC
- KVC是Key-value coding的缩写(键值编码)
1.键值编码是否会违背面向对象编程思想?
- key没有任何限制,只要知道类或者实例的私有成员名称就可以用key直接改变私有成员,所以会破坏面向对象编程思想。
2.valueForKey系统实现流程:
-
首先通过key,判断所访问的实例变量是否有对用get方法,如果存在会直接调用并结束调用流程,如果不存在会判断实例变量是否存在(系统方法,默认返回YES,可重写避免KVC破坏面向对象思想),如果不存在调用 valueForUndefinedKey方法并抛出异常结束调用。
valueForKey
3.访问器方法(Accessor Method)是否存在判断规则:
- getKey
- key
- isKey
4.实例变量(Instance var):
- _key
- _isKey
- key
- isKey
5.setValueForKey系统实现流程:
setValueForKey13、属性关键字
1.属性关键字可以分为哪几类?
- 读写权限:readonly; readwrite(默认)
- 原子性: atomic(默认); nonatomic(常用)
- 引用计数:retain(MRC)/strong(ARC);assign/unsafe_unretained(MRC);weak;copy。
2. atomic修饰的属性会产生什么样的效果:
- 保证赋值和获取是线程安全的,对于操作不是线程安全的。比如用atomic声明的数组,对该属性的赋值和获取是线程安全的,但是对于该数组的添加对象移除对象等操作不是线程安全的。
3.assign特点:
- assign用于修饰基本数据类型,如int、BOOL等。
- assign修饰对象类型时,不改变其引用计数。
- assign会产生悬垂指针(assign修饰的对象被释放之后,assign指针仍然指向原对象内存地址,如果通过assign指针继续访问原对象会导致内存泄露或者程序异常)。
4.weak特点:
- weak不改变被修饰对象的引用计数。
- weak修饰的对象在被释放之后会自动置为nil。
5.assign和weak关键字之间的区别?
- assign既可以修饰基本对象也可以修饰基本数据类型;weak可以修饰对象。
- assign修饰的对象被释放后任然会指向原对象的内存地址;weak修饰的对象被释放后会自动置为nil。
6.weak修饰的对象释放后为什么会被置为nil?
TODO
7.浅拷贝
- 只是对内存地址的copy,让目标对象指针和源对象指针指向同一片内存空间
- 会增加被拷贝对象的引用计数
- 不会发生新的内存分配
8.深拷贝
- 让目标对象指针和源对象指针指向两片内容相同的内存空间
- 深拷贝不会增加被拷贝对象的引用计数
- 深拷贝会发生新的内存分配
9.浅拷贝和深拷贝的区别?
- 浅拷贝不会开辟新的内存空间,深拷贝会。
- 浅拷贝会影响被拷贝对象的引用计数,深拷贝不会。
10.copy关键字
copy关键字- 可变对象的copy和mutableCopy都是深拷贝。
- 不可变对象的copy是浅拷贝,mutableCopy是深拷贝
- copy方法返回的都是不可变对象
- mutableCopy方法返回的都是可变对象
网友评论