iOS之性能优化面试题二

134 阅读4分钟

这是我参与11月更文挑战的第22天,活动详情查看:2021最后一次更文挑战

中级

  1. 重用和延迟加载(lazy load)Views
    • 更多的view意味着更多的渲染,也就是更多的CPU和内存消耗,对于那种嵌套了很多view在UIScrollView里面的app更是如此。
    • 这里我们用到的技巧就是模仿UITableViewUICollectionView的操作:不要一次创建所有的subview,而是当需要的时候才创建,当它们完成了使命,把他们放进一个可重用的队列中,这样的话你就只需要在滚动发生时创建你的views,避免了不划算的的内存分配。
  2. Cache,Cache,还是Cache!
    • 一个极好的原则就是,缓存所需要的,也就是那些不大可能改变但是需要经常读取的东西。
    • 我们能缓存些什么呢?一些选项是,远端服务器的响应,图片,甚至计算结果,比如UITableView的行高。
    • NSCacheNSDictionary类似,不同的是系统回收内存的时候它会自动删掉它的内容。
  3. 权衡渲染方法,保持性能还要bundle保持合适的大小
  4. 处理内存警告,移除对缓存,图片object和其他一些可以重创建的objects的strong refrences
  5. 重用大开销对象
  6. 一些objects的初始化很慢,比如NSDataFormatterNSCalendar,然而,你又不可避免的需要使用它们,比如从JSON或者XML中解析数据。想要避免使用这个对象的瓶颈你就需要重用它们,可以通过添加属性到你的class里或者创建静态变量来实现。
  7. 避免反复处理数据,在服务器端和客户端使用相同的数据结构很重要。
  8. 选择正确的数据格式。解析JSON会比XML更快一些,JSON也通常更小更便于传输。从iOS5起油了官方内建的JSON deserialization就更加方便使用了,但是XML也有XML的好处,比如使用SAX来解析XML就像解析本地文件一样,你不需要像解析json一样等到整个文档下载完成才开始解析,当你处理很大的数据的时候机会极大地减低内存消耗和增加性能。
  9. 正确设定背景图片
    • 全屏背景图,在view中添加一个UIImageView作为一个子View
    • 只是某个小的View的背景图,你就需要用UIColor的colorWithPatternImage来做了,它会更快的渲染也不会花费很多内存。
  10. 减少使用Web特性。想要更高的性能你就要调整下你的HTML了。第一件要做的事就是尽可能溢出不要的javascript,避免使用过大的框架,能只用原生js就更好了,尽可能异步加载例如用户行为统计script这种不影响页面表达的javascript,注意你使用的图片,保证图片的大小符合你使用的大小。
  11. Shadow Path。CoreAnimation不得不先在后台得出你的图形并加好阴影然后才渲染,这开销是很大的,使用shadowPath的话就避免了这个问题。使用shadowPath的话iOS就不必每次都计算如何渲染,它使用一个预先计算好的路径。但问题是自己计算path的话可能在某些View中比较困难,且每当view的frane变化的时候你都需要去update shadow path
  12. 优化TableView
    • 正确使用reuseIdentifier来重用cells
    • 尽量使用的view opaque ,包括cell自身
    • 避免渐变,图片缩放,后台选人
    • 缓存行高
    • 如果cell内现实的内容来自web,使用异步加载,缓存请求结果
    • 使用shadowPath来画阴影
    • 减少subviews的数量
    • 尽量不使用cellForRowAtIndexPath:,如果你需要使用它,只用一次然后缓存结果
    • 使用正确的数据结构来存储数据
    • 使用rowheight,sectionFooterHeight和sectionHeaderHeight来设定固定的高,不要请求delegate
  13. 选择正确的数据存储选项
    • 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 了。