版本记录
版本号 | 时间 |
---|---|
V1.0 | 2018.06.04 |
前言
我们在做一个APP时候需要注意哪些方面呢,接下来我们就看一下APP编程指南。里面有些可能大家在平时编程中都经历过,但是再系统的了解下也不是坏事。感兴趣的可以看上面写的几篇。
1. APP编程指南 (一) —— 基本概览(一)
2. APP编程指南 (二) —— 应用程序必须实现的行为(一)
3. APP编程指南 (三) —— 应用程序的后台执行(一)
4. APP编程指南 (四) —— 处理应用程序状态转换的策略(一)
5. APP编程指南 (五) —— 实现特定应用程序功能的策略(一)
6.APP编程指南 (六) —— 应用程序间通信(一)
Performance Tips - 性能提示
在您的应用程序开发的每一步中,请考虑您的设计选择对您应用程序整体性能的影响。 耗电量和内存消耗是iOS应用程序非常重要的考虑因素,还有许多其他考虑事项。 以下部分描述了在整个开发过程中应考虑的因素。
Reduce Your App’s Power Consumption - 减少应用程序的功耗
移动设备的功耗一直是个问题。 iOS中的电源管理系统通过关闭当前未使用的任何硬件功能来节省电量。您可以通过优化使用以下功能来帮助延长电池使用时间:
- CPU
- Wi-Fi,蓝牙和基带(EDGE,3G)无线电
-
Core Location
框架 - 加速度计
- 磁盘
优化的目标应该是尽可能以最有效的方式尽你所能完成最多的工作。您应该始终使用Instruments
来优化应用程序的算法。但即使是最优化的算法仍然会对设备的电池寿命产生负面影响。因此,在编写代码时应该考虑以下准则:
避免做需要
polling
轮询的工作。Polling
会阻止CPU进入休眠状态。除了轮询之外,还可以根据需要使用NSRunLoop
或NSTimer
类来安排工作。尽可能将共享的
UIApplication
对象的idleTimerDisabled属性设置为NO。闲置计时器在指定的闲置时间后关闭设备的屏幕。如果您的应用不需要屏幕保持开启状态,请让系统将其关闭。如果您的应用因屏幕关闭而出现副作用,则应修改代码以消除副作用,而不是不必要地禁用空闲计时器。尽可能合并工作以最大化空闲时间。一次执行一组计算通常耗费较少的电力,而不是在较长时间内以小块执行它们。定期进行少量的工作需要更频繁地唤醒CPU,并使其进入可执行任务的状态。
避免频繁访问磁盘。例如,如果您的应用程序将状态信息保存到磁盘,则只有当该状态信息发生更改时才进行此操作,并尽可能合并更改,以避免频繁地写入小的更改。
不要以比需要更快的速度画屏幕。在涉及到电力时,绘图是一项昂贵的操作。不要依靠硬件来限制帧速率。根据您的应用实际需要绘制尽可能多的帧。
如果您使用UIAccelerometer类接收常规加速度计事件,请在不需要时禁用这些事件的传递。同样,将事件传递的频率设置为适合您需要的最小值。有关更多信息,请参阅
Event Handling Guide for iOS
。
传输到网络的数据越多,必须使用更多的功率来运行无线电。实际上,访问网络是您可以执行的功耗最高的操作。您可以按照以下准则将时间最小化:
- 只在需要时连接到外部网络服务器,并且不要轮询这些服务器。
- 当你必须连接到网络时,传输完成这项工作所需的最小数据量。使用紧凑型数据格式,不要包含被忽略的多余内容。
- 以突发形式传输数据,而不是随着时间的推移传播数据包。当系统检测到缺少活动时,系统将关闭Wi-Fi和无线电。当它在较长时间内传输数据时,与在较短时间内传输相同数量的数据时相比,您的应用使用更多的电量。当使用
NSURLSession
类排队多个上传或下载任务时,将这些项目排队在一起,而不是等待一个完成,然后再开始下一个。系统管理自动执行排队的任务时,这是最有效的做法。 - 尽可能使用Wi-Fi连接到网络。 Wi-Fi使用更少的功率,并且优于蜂窝无线电。
- 如果您使用
Core Location
框架收集位置数据,请尽快禁用位置更新,并将距离过滤器和准确性级别设置为适当的值。Core Location
使用可用的GPS
,cell
和Wi-Fi
网络来确定用户的位置。尽管Core Location
尽量减少这些无线电的使用,但设置精确度和过滤器值可让Core Location
在不需要的情况下完全关闭硬件。有关更多信息,请参阅Location and Maps Programming Guide。
Instruments
应用程序包括几个用于收集与电量有关的信息的工具。您可以使用这些仪器收集有关功耗的一般信息,并收集硬件的特定测量结果,如Wi-Fi和蓝牙无线电,GPS接收器,显示器和CPU。您还可以在设备上启用Energy Diagnostics Logging
以收集信息。有关使用Instruments
收集与电量相关的数据的信息,请参见Instruments User Guide。有关如何在设备上启用Energy Diagnostics Logging
的信息,请参见 Instruments Help Topics。
Use Memory Efficiently - 有效地使用内存
我们鼓励应用程序使用尽可能少的内存,以便系统可以将更多应用程序保留在内存中,或者将更多内存专用于真正需要它的前台应用程序。 系统可用的可用内存量与应用程序的相对性能之间存在直接关系。 可用内存不足意味着系统更有可能在满足未来内存请求时遇到问题。
为确保始终有足够的可用内存,应尽量减少应用程序的内存使用量,并在系统要求释放内存时做出响应。
1. Observe Low-Memory Warnings - 观察低内存警告
当系统向您的应用程序发送低内存警告时,立即响应。低内存警告是您删除不需要的对象引用的时机。回应这些警告至关重要,因为未能这样做的应用程序更有可能被终止。系统使用以下API将内存警告提供给您的应用程序:
- 应用程序代理的applicationDidReceiveMemoryWarning:方法。
- 你的
UIViewController
类的didReceiveMemoryWarning
方法。 - UIApplicationDidReceiveMemoryWarningNotification通知。
- 调度DISPATCH_SOURCE_TYPE_MEMORYPRESSURE类型的源。这种技术是唯一可以用来区分内存压力严重程度的技术。
一旦收到任何这些警告,您的处理程序方法应立即释放任何不需要的内存。使用警告清除缓存并释放图像。如果您有大量未使用的数据结构,请将这些结构写入磁盘并释放数据的内存中副本。
如果您的数据模型包含已知可清除资源,则可以为UIApplicationDidReceiveMemoryWarningNotification
通知提供相应的管理器对象注册,并直接删除对其可清除资源的强引用。直接处理此通知可避免需要通过应用程序代理来路由所有内存警告调用。
注意:您可以使用
iOS Simulator
中的Simulate Memory Warning
命令在低内存条件下测试应用程序的行为。
2. Reduce Your App’s Memory Footprint - 减少应用程序的内存占用
从占用空间较小的开始,为您稍后扩展您的应用程序提供了更多空间。 表7-1列出了有关如何减少应用程序整体内存占用情况的一些提示。
Table 7-1 Tips for reducing your app’s memory footprint
Tip | Actions to take |
---|---|
消除内存泄漏 | 由于内存是iOS中的关键资源,因此您的应用程序不应该有内存泄漏。 使用Instruments 应用程序可以在模拟器和实际设备上追踪代码中的泄漏。 有关使用Instruments 的更多信息,请参见Instruments User Guide。 |
使资源文件尽可能小 | 文件驻留在磁盘上,但必须先装入内存才能使用。 压缩所有图像文件,使其尽可能小。 (要压缩PNG图像(iOS应用程序的首选图像格式)请使用pngcrush 工具。)可以使用NSPropertyListSerialization类以二进制格式将属性列表文件写入更小的属性列表文件。 |
对大型数据集使用Core Data 或SQLite |
如果您的应用程序操纵大量的结构化数据,请将其存储在Core Data 持久性存储中或SQLite 数据库中,而不是放在平面文件中。 Core Data 和SQLite 都提供了有效的方法来管理大型数据集,而无需将整个集合同时存储在内存中。 |
懒惰地加载资源 | 在实际需要之前,您不应该加载资源文件。 预取资源文件可能看起来像是一种节省时间的方式,但这种做法实际上会使您的应用程序立即变慢。 另外,如果你最终没有使用这个资源,那么加载它会浪费内存而没有什么用处。 |
3. Allocate Memory Wisely - 明智地分配内存
表7-2列出了有关改进应用程序中内存使用情况的几点建议。
Table 7-2 Tips for allocating memory
Tip | Actions to take |
---|---|
对资源施加大小限制 | 如果较小的资源就可以,那么就要避免加载较大的资源文件。 不要使用高分辨率图像,而要使用适合iOS设备的图像尺寸。 如果您必须使用大型资源文件,请在任何给定时间找到只加载所需文件的部分的方法。 例如,不是将整个文件加载到内存中,而是使用mmap 和munmap 函数将文件的部分映射到内存和清除到内存之外。 有关将文件映射到内存的更多信息,请参阅File-System Performance Guidelines 。 |
避免无限的问题集 | 无界问题集可能需要计算任意大量的数据。 如果该设置需要比可用内存更多的内存,则您的应用可能无法完成计算。 您的应用程序应尽可能避免使用这些集合,并处理已知内存限制的问题。 |
有关ARC和内存管理的详细信息,请参阅Transitioning to ARC Release Notes
Tune Your Networking Code - 调整您的网络代码
iOS中的网络堆栈包括多个用于通过iOS设备的无线电硬件进行通信的接口。 主要的编程接口是CFNetwork
框架,它基于BSD sockets
和Core Foundation
框架中的不透明类型构建,以便与网络实体进行通信。 您还可以使用Foundation框架中的NSStream类和系统的Core OS
层中的low-level BSD sockets
。
有关如何使用CFNetwork
框架进行网络通信的信息,请参阅CFNetwork Framework Reference和CFNetwork Programming Guide。 有关使用NSStream
类的信息,请参阅Foundation Framework Reference。
1. Tips for Efficient Networking - 高效网络提示
实现通过网络接收或传输数据的代码是设备上功耗最高的操作之一。最大限度地减少传输或接收数据的时间有助于延长电池寿命。为此,编写与网络相关的代码时应考虑以下提示:
- 对于您控制的协议,将您的数据格式定义为尽可能紧凑。
- 避免使用聊天协议。
- 只要有可能就以突发形式传输数据包。
蜂窝和Wi-Fi无线电设计在没有活动时就降低功耗。然而,取决于radio
,这样做可能需要几秒钟的时间。如果您的应用程序每隔几秒传输一小段数据,则无线电可能会保持高耗能状态并继续耗电,即使它们实际上没有做任何事情。与更频繁地传输少量数据相比,最好一次或以相对较大的时间间隔传输大量数据。
通过网络进行通信时,数据包可能随时丢失。因此,在编写网络代码时,应确保在涉及故障处理时使其尽可能健壮。实现响应网络条件变化的处理程序是完全合理的,但如果这些处理程序没有一致调用,请不要感到惊讶。例如,Bonjour
网络回调可能并不总是立即响应网络服务的消失而被调用。 Bonjour
系统服务在收到服务正在消失的通知时立即调用浏览回调,但网络服务可能会在没有通知的情况下消失。如果提供网络服务的设备意外丢失网络连接或通知在传输中丢失,则可能会出现这种情况。
2. Using Wi-Fi - 使用Wi-Fi
如果您的应用使用Wi-Fi无线电访问网络,则必须通过在应用的Info.plist
文件中包含UIRequiresPersistentWiFi
密钥来通知系统。如果包含此密钥,系统就会知道它应该在检测到任何活动的Wi-Fi热点时显示网络选择对话框。它还让系统知道它不应该在您的应用运行时尝试关闭Wi-Fi硬件。
为了防止Wi-Fi硬件使用过多的电量,iOS有一个内置的计时器,如果没有正在运行的应用程序通过UIRequiresPersistentWiFi
密钥请求使用它,则会在30分钟后完全关闭硬件。如果用户启动包含密钥的应用,iOS会在应用生命周期内有效地禁用该计时器。但是,一旦该应用程序退出或暂停,系统将重新启用计时器。
注意:请注意,即使
UIRequiresPersistentWiFi
的值为true
,在设备空闲(即屏幕锁定)时也不起作用。该应用程序被视为不活动,虽然它可能在某些级别上运行,但它没有Wi-Fi连接。
有关UIRequiresPersistentWiFi
密钥和Info.plist
文件密钥的更多信息,请参阅The Information Property List File。
3. The Airplane Mode Alert - 飞行模式警报
如果您的应用程序在设备处于飞行模式时启动,系统可能会显示警报以通知用户该事实。 只有满足以下所有条件时,系统才会显示此警报:
- 您的应用的信息属性列表(Info.plist)文件包含
UIRequiresPersistentWiFi
密钥,并且该密钥的值设置为true
。 - 您的应用在设备当前处于飞行模式时启动。
- 切换到飞行模式后,设备上的Wi-Fi尚未被手动重新启用。
Improve Your File Management - 改进你的文件管理
最大限度地减少您写入磁盘的数据量。 文件操作相对较慢,涉及写入寿命有限的闪存驱动器。 一些特定的提示可帮助您最大限度地减少与文件相关的操作
- 只写入已更改的文件部分,并在可能的时候汇总更改。 避免写出整个文件只是为了改变几个字节。
- 定义文件格式时,将经常修改的内容分组在一起,以尽量减少每次需要写入磁盘的块的总数。
- 如果您的数据由随机访问的结构化内容组成,请将其存储在
Core Data
持久性存储或SQLite
数据库中,特别是如果您操作的数据量可能增长到超过几兆字节。
避免将缓存文件写入磁盘。 这条规则的唯一例外是当您的应用程序退出时,您需要编写状态信息,以便在下次启动时将您的应用程序重新置于相同的状态。
Make App Backups More Efficient - 使应用程序备份更加高效
无论是通过iCloud还是用户将设备与iTunes同步,备份都会发生。 备份期间,文件将从设备传输到用户的计算机或iCloud帐户。 应用沙箱中文件的位置决定了是否备份和恢复这些文件。 如果您的应用程序创建了许多定期更改的大文件并将其放入备份的位置,则备份可能会因此而变慢。 在编写文件管理代码时,需要注意这一事实。
1. App Backup Best Practices - 应用备份最佳实践
您无需以任何方式为备份和恢复操作准备您的应用程序。 具有活动iCloud帐户的设备在适当的时候将其应用程序数据备份到iCloud。 对于插入计算机的设备,iTunes会执行应用程序数据文件的增量备份。 但是,iCloud
和iTunes
不备份以下目录的内容:
/AppName.app /Library/Caches /tmp
为防止同步过程花费很长时间,请选择将文件放置在应用程序主目录中的位置。 存储大型文件的应用程序可能会减慢备份到iTunes
或iCloud
的过程。 这些应用程序还可能消耗大量用户的可用存储空间,这可能会鼓励用户删除应用程序或禁用该应用程序的数据备份到iCloud。 考虑到这一点,您应该根据以下准则存储应用程序数据:
- 关键数据应该存储在
目录中。关键数据是您的应用无法重新创建的任何数据,例如用户文档和其他用户生成的内容。/ Documents - 支持文件包括应用程序下载或生成的文件,并且您的应用程序可以根据需要重新创建。存储应用程序支持文件的位置取决于当前的iOS版本。
- 在iOS 5.1和更高版本中,将支持文件存储在
目录中,并使用setResourceValue:forKey:error:方法将NSURLIsExcludedFromBackupKey属性添加到相应的NSURL对象。 (如果您使用的是/ Library / Application Support Core Foundation
,请使用kCFURLIsExcludedFromBackupKey函数将kCFURLIsExcludedFromBackupKey项添加到CFURLRef
对象中。)应用此属性可防止将文件备份到iTunes
或iCloud
。如果您有大量支持文件,则可以将它们存储在自定义子目录中,并将扩展属性应用于目录。 - 在iOS 5.0及更低版本中,将支持文件存储在
目录中以防止它们被备份。如果您的目标是/ Library / Caches iOS 5.0.1
,有关如何从备份中排除文件的信息请参阅How do I prevent files from being backed up to iCloud and iTunes?。
- 在iOS 5.1和更高版本中,将支持文件存储在
- 缓存的数据应该存储在
目录中。您应该在Caches目录中放置的文件示例包括(但不限于)数据库缓存文件和可下载内容(如杂志,报纸和地图应用程序使用的内容)。您的应用程序应该能够正常处理系统删除缓存数据以释放磁盘空间的情况。/ Library / Caches - 临时数据应该存储在
目录中。临时数据包含您不需要长时间存储的任何数据。请记住在完成这些文件后删除这些文件,以便它们不会继续占用用户设备上的空间。/ tmp
虽然iTunes自己备份应用程序包,但在每次同步操作期间都不会这样做。当设备下一次与iTunes同步时,直接从设备购买的应用会得到备份。不过,除非应用程序包本身已更改(例如,因为应用程序已更新),否则在后续同步操作期间不会备份应用程序。
有关如何在应用程序中使用目录的其他指导,请参阅File System Programming Guide。
2. Files Saved During App Updates - 在应用更新期间保存的文件
当用户下载应用程序更新时,iTunes会将更新安装到新的应用程序目录中。 然后在删除旧安装之前,将用户的数据文件从旧安装移到新的应用目录。 保证在更新过程中保留以下目录中的文件:
/Documents /Library
尽管其他用户目录中的文件也可能被移动,但更新后不应依赖它们。
Move Work off the Main Thread - 限制主线程工作类型
请务必限制您在应用程序主线程中完成的工作类型。主线程是您的应用程序处理触摸事件和其他用户输入的地方。为确保您的应用始终对用户做出响应,您绝不应使用主线程执行长时间运行或潜在无界的任务,例如访问网络的任务。相反,您应该始终将这些任务移动到后台线程。这样做的首选方法是使用Grand Central Dispatch(GCD)
或NSOperation
对象异步执行任务。
将任务移动到后台中可让您的主线程空闲以继续处理用户输入,这在您的应用程序启动或退出时尤其重要。在这段时间内,您的应用期望可以及时响应事件。如果您的应用程序的主线程在启动时被阻止,系统甚至可能会在完成启动之前终止应用程序。如果主线程在退出时被阻塞,系统可能会在应用程序有机会写出关键用户数据之前杀死应用程序。
有关使用GCD
,operation
对象和线程的更多信息,请参见Concurrency Programming Guide。
后记
本篇主要讲述了性能方面上的一些小点和注意事项,感兴趣的给个赞或者关注~~~