这是我参与11月更文挑战的第22天,活动详情查看:2021最后一次更文挑战。
中级
- 重用和延迟加载(
lazy load
)Views- 更多的view意味着更多的渲染,也就是更多的CPU和内存消耗,对于那种嵌套了很多view在
UIScrollView
里面的app更是如此。 - 这里我们用到的技巧就是模仿
UITableView
和UICollectionView
的操作:不要一次创建所有的subview,而是当需要的时候才创建,当它们完成了使命,把他们放进一个可重用的队列中,这样的话你就只需要在滚动发生时创建你的views,避免了不划算的的内存分配。
- 更多的view意味着更多的渲染,也就是更多的CPU和内存消耗,对于那种嵌套了很多view在
- Cache,Cache,还是Cache!
- 一个极好的原则就是,缓存所需要的,也就是那些不大可能改变但是需要经常读取的东西。
- 我们能缓存些什么呢?一些选项是,远端服务器的响应,图片,甚至计算结果,比如
UITableView
的行高。 NSCache
和NSDictionary
类似,不同的是系统回收内存的时候它会自动删掉它的内容。
- 权衡渲染方法,保持性能还要
bundle
保持合适的大小 - 处理内存警告,移除对缓存,图片object和其他一些可以重创建的objects的
strong refrences
- 重用大开销对象
- 一些objects的初始化很慢,比如
NSDataFormatter
和NSCalendar
,然而,你又不可避免的需要使用它们,比如从JSON或者XML中解析数据。想要避免使用这个对象的瓶颈你就需要重用它们,可以通过添加属性到你的class里或者创建静态变量来实现。 - 避免反复处理数据,在服务器端和客户端使用相同的数据结构很重要。
- 选择正确的数据格式。解析JSON会比XML更快一些,JSON也通常更小更便于传输。从iOS5起油了官方内建的JSON deserialization就更加方便使用了,但是XML也有XML的好处,比如使用SAX来解析XML就像解析本地文件一样,你不需要像解析json一样等到整个文档下载完成才开始解析,当你处理很大的数据的时候机会极大地减低内存消耗和增加性能。
- 正确设定背景图片
- 全屏背景图,在view中添加一个UIImageView作为一个子View
- 只是某个小的View的背景图,你就需要用UIColor的
colorWithPatternImage
来做了,它会更快的渲染也不会花费很多内存。
- 减少使用Web特性。想要更高的性能你就要调整下你的HTML了。第一件要做的事就是尽可能溢出不要的
javascript
,避免使用过大的框架,能只用原生js就更好了,尽可能异步加载例如用户行为统计script这种不影响页面表达的javascript
,注意你使用的图片,保证图片的大小符合你使用的大小。 Shadow Path
。CoreAnimation不得不先在后台得出你的图形并加好阴影然后才渲染,这开销是很大的,使用shadowPath的话就避免了这个问题。使用shadowPath
的话iOS就不必每次都计算如何渲染,它使用一个预先计算好的路径。但问题是自己计算path的话可能在某些View中比较困难,且每当view的frane变化的时候你都需要去update shadow path
- 优化TableView
- 正确使用reuseIdentifier来重用cells
- 尽量使用的view opaque ,包括cell自身
- 避免渐变,图片缩放,后台选人
- 缓存行高
- 如果cell内现实的内容来自web,使用异步加载,缓存请求结果
- 使用shadowPath来画阴影
- 减少subviews的数量
- 尽量不使用cellForRowAtIndexPath:,如果你需要使用它,只用一次然后缓存结果
- 使用正确的数据结构来存储数据
- 使用rowheight,sectionFooterHeight和sectionHeaderHeight来设定固定的高,不要请求delegate
- 选择正确的数据存储选项
- NSUserDefaults的问题是什么?虽然它很nice也很便捷,但是它只适用于小数据,比如一些简单的布尔型的设置选项,再大点你就要考虑其他方式了。
- XML这种结构化档案呢?总体来说,你需要读取整个文件到内存里去解析,这样是很不经济的,使用SAX又是一个很麻烦的事情。
- NSCoding?不幸的是,他也需要读写文件,所以也有以上问题。
- 在这种应用场景下,使用SQLite或者Core Data比较好,使用这些技术你用特定的查询语句就能只加载你需要的对象
- 在性能层面来讲,SQLite和Core Data是很相似的,它们的不同在于具体使用方法
- Core Data代表一个对象的graph model,但SQLite就是一个DBMS。
- Apple在一般情况下建议使用CoreData,但是如果你有理由不使用它,那么就去使用更加底层的 SQLite 吧。
- 如果你使用SQLite,你可以用FMDB这个库来简化SQLite的操作,这样你就不用花很多经历了解 SQLite 的 C API 了。