开发完成不是最终结果,怎样完成优化?
Posted kaihaOS
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了开发完成不是最终结果,怎样完成优化?相关的知识,希望对你有一定的参考价值。
1. 如何让你的应用程序更加省电? 答: (1) 如果程序用到定位,需要在定位完毕之后关闭定位,或者降低定位的频率,不停的定位会消耗电量。 (2) 如果用到了蓝牙,需要使用蓝牙时候开启蓝牙,蓝牙用完之后关闭蓝牙,蓝牙也很耗电。 (3) 优化算法,减少循环次数,大量循环会让 CPU 一直处于忙碌状态,特别费电。 (4) 不要使用网络轮询,使用推送。 (5)timer 的时间间隔不宜太短,满足需求即可。 (5) 不要频繁刷新页面,能刷新 1 行 cell ,不要 reloadData 。 (6) 切勿让屏幕长亮。 (7) 线程适量,不宜过多。 57. 简单描述你一下在开发的过程中,如何实现程序的性能优化? 答:我在开发的过程中会注意一下几点来优化程序性能: 1. 避免庞大的 XIB 2. 使用懒加载的方式延迟加载界面 3. 避免反复处理数据 4. 避免使用 NSDateFormatter 和 NSCalendar 。 5. 图片缓存的取舍 UIImage 加载图片方式一般有两种 : A : imagedNamed 初始化 B : imageWithContentsOfFile 初始化 二者不同之处在于 ,imageNamed 默认加载图片成功后会内存中缓存图片 , 这个方法用一个指定的名字在系统缓存中查找并返回一个图片对象 . 如果缓存中没有找到相应的图片对象 , 则从指定地方加载图片然后缓存对象,并返回这个图片对象 . 而 imageWithContentsOfFile 则仅只加载图片 , 不缓存 . 大量使用 imageNamed 方式会在不需要缓存的地方额外增加开销 CPU 的时间来做这件事 . 当应用程序需要加载一张比较大的图片并且使用一次性,那么其实是没有必要去缓存这个图片的,用 imageWithContentsOfFile 是最为经济的方式 , 这样不会因为 UIImage 元素较多情况下, CPU 会被逐个分散在不必要缓存上浪费过多时间 . 使用场景需要编程时,应该根据实际应用场景加以区分, UIImage 虽小,但使用元素较多问题会有所凸显 . 8 、 tableView 的重用机制? 查看 UITableView 头文件,会找到 NSMutableArray* visiableCells ,和 NSMutableDictnery*reusableTableCells 两个结构。 visiableCells 内保存当前显示的 cells , reusableTableCells 保存可重用的 cells 。 TableView 显示之初, reusableTableCells 为空,那么 tableViewdequeueReusableCellWithIdentifier:CellIdentifier 返回 nil 。开始的 cell 都是通过 [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] 来创建,而且 cellForRowAtIndexPath 只是调用最大显示 cell 数的次数。 比如:有 100 条数据, iPhone 一屏最多显示 10 个 cell 。程序最开始显示 TableView 的情况是: 1. 用 [[UITableViewCellalloc] initWithStyle:UITableViewCellStyleDefaultreuseIdentifier:CellIdentifier] 创建 10 次 cell ,并给 cell 指定同样的重用标识 ( 当然,可以为不同显示类型的 cell 指定不同的标识 ) 。并且 10 个 cell 全部都加入到 visiableCells 数组, reusableTableCells 为空。 2. 向下拖动 tableView ,当 cell1 完全移出屏幕,并且 cell11( 它也是 alloc 出来的,原因同上 ) 完全显示出来的时候。 cell11 加入到 visiableCells , cell1 移出 visiableCells , cell1 加入到 reusableTableCells 。 3. 接着向下拖动 tableView ,因为 reusableTableCells 中已经有值,所以,当需要显示新的 cell , cellForRowAtIndexPath 再次被调用的时候, tableViewdequeueReusableCellWithIdentifier:CellIdentifier ,返回 cell1 。 cell1 加入到 visiableCells , cell1 移出 reusableTableCells ; cell2 移出 visiableCells , cell2 加入到 reusableTableCells 。之后再需要显示的 Cell 就可以正常重用了。 如何减小一个应用程序占用存储空间? 检查程序 去掉多余的 xib 。 ios App Store 相关因素作为提交到 App Store 中 app 里的可执行文件是被加过密的。加密的副作用是可执行文件的压缩效果没有之前的好了。 Build Settings 编译选项,将 build setting 中的 Optimization Level 设置为 Fastest, Smallest [-Os]; 将 build setting 中的 Strip Debug Symbols During Copy 设置为 YES(COPY_PHASE_STRIP = YES) ,这样可以减小编译出二进制文件的尺寸。 Target 针对较少的 CPUs 对程序指定的特定 CPU 类型做优化处理,以生成相对于的可执行文件。不同的硬件,将运行不同的可执行代码。虽然这样优化后的程序,只能针对某些设备运行,但是这大大减小可执行程序的大小。要想只设定特定类型的 CPUs ,可以修改 build setting 中的 Architectures ,将其从 Standard $(ARCHS_STANDARD) 修改为你希望支持的列表中对应的特定类型 CPU 。有效的 CPU 名称列在 Valid Architectures (VALID_ARCHS) build setting 中。请不要修改 Valid Architectures 设置项,最好由 Xcode 管理。尽量使用 8-bit 图片。使用 8-bit 的 PNG 图片,比 32-bit 的图片能减少 4 倍的压缩率。由于 8-bit 的图片支持最多 256 种不同的颜色,所以 8-bit 的图片一般只应该用于一小部分 的颜色图片。例如灰度图片最好使用 8-bit 如何提高一个应用程序的性能? 1、使用ARC减少内存失误,dealloc需要重写并对属性置nil。2、重用。3、尽量少使用透明或半透明。会产生额外的运算。4、少用运算获得圆角,不论view.maskToBounds还是layer.clipToBounds都会有很大资源开销,必须要用圆角的话不如图片本身就做成圆角。5、不要阻塞主线程。6、使用正确的容器类型。7、图片与imageView相同大小避免多余运算。8、使用懒加载。9、使用绘制。 如何优化内存? (1). 用ARC管理内存 ARC(Automatic ReferenceCounting, 自动引用计数)和iOS5一起发布,它避免了最常见的也就是经常是由于我们忘记释放内存所造成的内存泄露。它自动为你管理retain和release的过程,除了帮你避免内存泄露,ARC还可以帮你提高性能,它能保证释放掉不再需要的对象的内存。 (2). 在正确的地方使用reuseIdentifier 一个开发中常见的错误就是没有给UITableViewCells, UICollectionViewCells,甚至是UITableViewHeaderFooterViews设置正确的reuseIdentifier。 (3).尽量把views设置为透明 如果你有透明的Views你应该设置它们的opaque属性为YES。 原因是这会使系统用一个最优的方式渲染这些views。如果设为YES,渲染系统就认为这个view是完全不透明的,这使得渲染系统优化一些渲染过程和提高性能。如果设置为NO,渲染系统正常地和其它内容组成这个View。默认值是YES。 (4).避免过于庞大的XIB 当你加载一个XIB的时候所有内容都被放在了内存里,包括任何图片。如果有一个不会即刻用到的view,你这就是在浪费宝贵的内存资源了。 (5).不要阻塞主线程 永远不要使主线程承担过多。因为UIKit在主线程上做所有工作,渲染,管理触摸反应,回应输入等都需要在它上面完成。 一直使用主线程的风险就是如果你的代码真的block了主线程,你的app会失去反应。 大部分阻碍主进程的情形是你的app在做一些牵涉到读写外部资源的I/O操作,比如存储或者网络。 (6). 在Image Views中调整图片大小 如果要在`UIImageView`中显示一个来自bundle的图片,你应保证图片的大小和UIImageView的大小相同。在运行中缩放图片是很耗费资源的,特别是`UIImageView`嵌套在`UIScrollView`中的情况下。 如果图片是从远端服务加载的你不能控制图片大小,比如在下载前调整到合适大小的话,你可以在下载完成后,最好是用background thread,缩放一次,然后在UIImageView中使用缩放后的图片。 (7). 选择正确的Collection 学会选择对业务场景最合适的类或者对象是写出能效高的代码的基础。当处理collections时这句话尤其正确。 一些常见collection的总结: · Arrays: 有序的一组值。使用index来lookup很快,使用value lookup很慢,插入/删除很慢。 ·Dictionaries: 存储键值对。用键来查找比较快。 · Sets: 无序的一组值。用值来查找很快,插入/删除很快。 (8). 打开gzip压缩 大量app依赖于远端资源和第三方API,你可能会开发一个需要从远端下载XML, JSON, html或者其它格式的app。 问题是我们的目标是移动设备,因此你就不能指望网络状况有多好。一个用户现在还在edge网络,下一分钟可能就切换到了3G。不论什么场景,你肯定不想让你的用户等太长时间。 减小文档的一个方式就是在服务端和你的app中打开gzip。这对于文字这种能有更高压缩率的数据来说会有更显著的效用。 好消息是,iOS已经在NSURLConnection中默认支持了gzip压缩,当然AFNetworking这些基于它的框架亦然。像Google App Engine这些云服务提供者也已经支持了压缩输出。 (9). 重用和延迟加载(lazy load) Views 更多的view意味着更多的渲染,也就是更多的CPU和内存消耗,对于那种嵌套了很多view在UIScrollView里边的app更是如此。 这里我们用到的技巧就是模仿`UITableView`和`UICollectionView`的操作:不要一次创建所有的subview,而是当需要时才创建,当它们完成了使命,把他们放进一个可重用的队列中。 这样的话你就只需要在滚动发生时创建你的views,避免了不划算的内存分配。 创建views的能效问题也适用于你app的其它方面。想象一下一个用户点击一个按钮的时候需要呈现一个view的场景。有两种实现方法: 1. 创建并隐藏这个view当这个screen加载的时候,当需要时显示它; 2. 当需要时才创建并展示。 每个方案都有其优缺点。用第一种方案的话因为你需要一开始就创建一个view并保持它直到不再使用,这就会更加消耗内存。然而这也会使你的app操作更敏感因为当用户点击按钮的时候它只需要改变一下这个view的可见性。 第二种方案则相反-消耗更少内存,但是会在点击按钮的时候比第一种稍显卡顿。 (10). Cache, Cache, 还是Cache! 一个极好的原则就是,缓存所需要的,也就是那些不大可能改变但是需要经常读取的东西。 我们能缓存些什么呢?一些选项是,远端服务器的响应,图片,甚至计算结果,比如UITableView的行高。 NSURLConnection默认会缓存资源在内存或者存储中根据它所加载的HTTP Headers。你甚至可以手动创建一个NSURLRequest然后使它只加载缓存的值。 (11).权衡渲染方法 在iOS中可以有很多方法做出漂亮的按钮。你可以用整幅的图片,可调大小的图片,uozhe可以用CALayer, CoreGraphics甚至OpenGL来画它们。 当然每个不同的解决方法都有不同的复杂程度和相应的性能。 简单来说,就是用事先渲染好的图片更快一些,因为如此一来iOS就免去了创建一个图片再画东西上去然后显示在屏幕上的程序。问题是你需要把所有你需要用到的图片放到app的bundle里面,这样就增加了体积–这就是使用可变大小的图片更好的地方了:你可以省去一些不必要的空间,也不需要再为不同的元素(比如按钮)来做不同的图。 然而,使用图片也意味着你失去了使用代码调整图片的机动性,你需要一遍又一遍不断地重做他们,这样就很浪费时间了,而且你如果要做一个动画效果,虽然每幅图只是一些细节的变化你就需要很多的图片造成bundle大小的不断增大。 总得来说,你需要权衡一下利弊,到底是要性能能还是要bundle保持合适的大小。 (12).处理内存警告 一旦系统内存过低,iOS会通知所有运行中app。如果你的app收到了内存警告,它就需要尽可能释放更多的内存。最佳方式是移除对缓存,图片object和其他一些可以重创建的objects的strong references. 幸运的是,UIKit提供了几种收集低内存警告的方法: · 在app delegate中使用`applicationDidReceiveMemoryWarning:`的方法 · 在你的自定义UIViewController的子类(subclass)中覆盖`didReceiveMemoryWarning` · 注册并接收UIApplicationDidReceiveMemoryWarningNotification的通知 一旦收到这类通知,你就需要释放任何不必要的内存使用。 例如,UIViewController的默认行为是移除一些不可见的view,它的一些子类则可以补充这个方法,删掉一些额外的数据结构。一个有图片缓存的app可以移除不在屏幕上显示的图片。 (13).重用大开销对象 一些objects的初始化很慢,比如NSDateFormatter和NSCalendar。然而,你又不可避免地需要使用它们,比如从JSON或者XML中解析数据。 想要避免使用这个对象的瓶颈你就需要重用他们,可以通过添加属性到你的class里或者创建静态变量来实现。 注意如果你要选择第二种方法,对象会在你的app运行时一直存在于内存中,和单例(singleton)很相似。 还需要注意的是,其实设置一个NSDateFormatter的速度差不多是和创建新的一样慢的!所以如果你的app需要经常进行日期格式处理的话,你会从这个方法中得到不小的性能提升。 (14). 减少使用Web特性 UIWebView很有用,用它来展示网页内容或者创建UIKit很难做到的动画效果是很简单的一件事。 但是你可能有注意到UIWebView并不像不像驱动Safari的那么快。这是由于以JIT compilation为特色的Webkit的Nitro Engine的限制。 所以想要更高的性能你就要调整下你的HTML了。第一件要做的事就是尽可能移除不必要的javascript,避免使用过大的框架。能只用原生js就更好了。 另外,尽可能异步加载例如用户行为统计script这种不影响页面表达的javascript。 最后,永远要注意你使用的图片,保证图片的符合你使用的大小。使用Sprite sheet提高加载速度和节约内存。 (15). 优化Table ViewTable view需要有很好的滚动性能,不然用户会在滚动过程中发现动画的瑕疵。为了保证table view平滑滚动,确保你采取了以下的措施: · 正确使用`reuseIdentifier`来重用cells · 尽量使所有的view opaque,包括cell自身 · 避免渐变,图片缩放,后台选人 · 缓存行高 · 如果cell内现实的内容来自web,使用异步加载,缓存请求结果 · 使用`shadowPath`来画阴影 · 减少subviews的数量- 尽量不适用`cellForRowAtIndexPath:`,如果你需要用到它,只用一次然后缓
以上是关于开发完成不是最终结果,怎样完成优化?的主要内容,如果未能解决你的问题,请参考以下文章