iOS编程实战
读书笔记
1.弱引用容器
常见的容器有NSArray
, NSSet
和 NSDictionary
;
NSArray
和NSSet
会保留保存在其中的对象,
NSDictionary
不光会保留值,还要复制键.
从iOS6开始有了新的容器类:NSPointerArray
, NSHashTable
和NSMapTable
, 它们统称为指针容器类, 有时候配置为使用NSPointerFuntions
类
- NSPointerArray 类似于 NSArray
- NSHashTable 类似于 NSSet
- NSMapTable 类似于 NSDictionary
这些新容器都可以配置为持有弱引用/非对象的指针或者其他罕见情形, NSPointerArray还有一个好处是可以存户Null值.
2. UIKit和视图绘图周期
- iOS在运行循环中整合所有的绘图请求, 并一次将他们绘制出来
- 不能在主线程中进行复杂的处理
- 不能在主线程之外的主视图上下文中绘制. 开发者需要检查每个UIKit方法以确保它没有主线程需求. 只要不是在主线程绘制. 一些UIKit方法是可以在后台线程中使用的.
3.视图绘制与视图布局
- 如果一个视图调用了 setNeedsDisplay方法, 他就被标记为"需要刷新的", 并且会在下一次绘图周期中重新绘制.
- 如果数据改变后只需要进行布局更新(而非绘制), 则可以调用 setNeedsDisplay方法.
4.混用UIKit和Core Graphics
在 drawRect: 方法之外, 你可能会发现使用Core Graphics绘制的东西上下颠倒. 这个是因为坐标系不同的原因. UIKit是左上点为原点, 而Core Graphics的原点是在左下.
只要使用 drawRect: 方法中的 UIGraphicsGetCurrentContext 返回的上下文, 那么一切都是正常的, 因为这个上下文是已经翻转过的. 不过, 如果使用CGBitmapContextCreate 这样的函数创建自己的上下文, 它会以左下角为原点. 可以进行反向计算或者翻转上下文:
- Core Graphics 转 UIKit, 先平移了上下文的高度并使用一个负数比例进行反转.
CGContextTranslateCTM(context, 0.0f, height);
CGContextScaleCTM(context, 1.0f, -1.0f);
- UIKit 转 Core Graphics 先反转, 然后平移.
CGContextScaleCTM(context, 1.0f, -1.0f);
CGContextTranslateCTM(context, 0.0f, -height);
5.透明(alpha),不透明(opaque)与隐藏(hidden)
看似有关实际无关的属性
alpha
alpha 属性决定了视图会通过像素显示多少信息. 1
意味着所有的视图信息都在像素上表现出来, 0
意味着没有视图信息能在像素上显示出来.
iPhone上没有东西是真正透明的. 说到底, 它只是关于如何绘制像素的问题.
opaque
opaque并不会实际升高或降低它的透明度. 绘图系统会根据opaque来优化. 如果视图标记为opaque, 便是向绘图系统'许诺'即将绘制的每一个像素都要使用全部透明的颜色. 这便允许绘图系统忽略在下面的视图, 这样可以改善性能, 尤其是在进行变性时. 但是视图中有特定的透明区域, 或者并不绘制矩形所有像素, 设置opaque会导致不可预测的结果.设置一个非透明的backgroundColor属性可以确保绘制所有像素.
与opaque紧密相关的是 clearsContextBeforeDrawing. 它的默认值为Yes, 而且会在调用 drawRect:之前将上下文设置为透明黑底. 这会避免视图中的任何垃圾数据. 这种操作非常快, 不过如果打算绘制每一个像素, 将其设置为 NO 可能会好些.
hidden
hidden代表视图并不会被绘制. 它通常等同于 alpha 为0, 以为hidden属性不能产生动画效果. 所以通常还是以动画模拟 alpha 到值 0的方法隐藏视图.
你可以创建一个透明视图来接收事件. alpha 为 1 , opaque 为 NO 且 backgroundColor 为nil 或 [UIColor clearColor] 来接收触摸事件. 如果用于碰撞检测, 拥有透明背景的视图仍然被认为是可视的.