即时篇稿子之所以备忘录的花样集合了25个技巧及诀窍可以用来增强而的app性能。这首文章用备忘录的花样集合了25个技术和诀窍可以用来增进而的app性能。

25长条提高iOS App性能的技能和诀窍

当我们开发iOS应用时,好的性质对咱的App来说是老要紧的。你的用户为指望这样,但是若您的app表现的感应迟钝或深缓慢也会伤及公的按。 

   
 然而,由于IOS设备的限定有时坏不便办事得慌不错。我们付出时有很多亟待我们铭记这些易忘的支配对性能的影响。 

   
 这是干什么我写就首文章的故。这篇稿子之所以备忘录的形式集合了25单技术和诀窍可以据此来增进而的app性能。所以保持阅读来受你未来的App一个颇不错的加强。 

*   
  Note:在优化代码之前,必须管发生只需要解决的题材!不要陷入”pre-optimizing(预优化)”你的代码。勤
用Instruments分析你的代码,发现任何一个欲增强的地方。Matt
Galloway写了一个使Instruments优化代码的底课*

*    *

*    以下这些技术分为三单不等那个的级别—基础,中级,高级。 *

   基础

*  * 这些技术你一旦连接想方实现以您出的App中。 

   1. 因此ARC去管理内存(Use ARC to Manage Memory)

   2.得体的地方采取reuseIdentifier(Use a reuseIdentifier Where
Appropriate)

   3.尽可能设置视图为非透明(Set View as Opaque When Possible)

   4.幸免臃肿的XIBs文件(Avoid Fat XiBs)

   5.不要阻塞主进程(Don’t Block the Main Thread)

   6.调整图像视图中之图像尺寸(Size Images to Image Views)

   7.挑正确集合(Choose the Correct Collection)

   8.启用Gzip压缩(Enable GZIP Compression)

   

*   中级*

*   *这些技术是当您遇见再复杂的景象的时用。

    9. 收录和推迟加载视图(Reuse and Lazy Load Views)

   10.缓存,缓存,缓存(Cache,Cache,Cache)

   11.考虑绘图(Consider Drawing)

   12.处理外存警告(Handle Memory Warnings)

   13.重据此老开支对象(Reuse Expensive Objects)

   14.运精灵表(Use Sprite Sheets )

   15.避免双重处理数量(Avoid Re-Processing Data)

   16.选对的数据格式(Choose the Right Data Format)

   17.宜的设置背景图片(Set  Background Images Appropriately)

   18.精减你的大网占用(Reduce Your Web Footprint)  

   19.安装阴影路径(Set the Shadow Path )

   20.您的报表视图Optimize Your Table Views)

   21.抉择正确的数据存储方(Choose Correct Data Storage Option)

   

   高级


 *这些技术你应当仅仅当您生积极当它们会解决此问题,而且若道之所以她非常舒心的时候使用。

   22.增速开动时间(Speed up Launch Time )

   23.采取机动释放池(Use AutoRelease Pool)

   24.缓存图像(Cache Images-Or not )

   25.尽可能避免日期格式化器(Avoid Date Formatters Where Possible)  

   没有其他的,一起错过看望这些技能吧!

  

 基础的属性提升

1)用ARC去管理内存

   ARC是伴随IOS5 一起发布的,它用来排遣周边的底内存泄漏。

   ARC是”Automatic Reference
Counting”的缩写。它自动管理而代码中之retain/release循环,这样您就算不用手动做就事情了。

   下面就段代码展示了创一个view的常用代码

 

[cpp] view
plain copy

 

  1. UIView *view =[[UIView alloc] init];  
  2. //…  
  3. [self.view addSubview:view];  
  4. [view release];  

 
 这里太容易忘在代码结束的地方调用release,ARC将会见自行的,底层的啊你开这些干活儿。

 
 除了帮忙您若避免内存泄漏,ARC还会管对象不再动用时立马被回收来增进你的习性。你应有于您的工程里基本上用ARC。

   这里是一些上学又多关于ARC的大棒的资源

  • Apple’s official
    documentation 苹果的官文档。
  • Matthijs Hollemans’s Beginning ARC in iOS
    Tutorial
  • Tony Dahbura’s How To Enable ARC in a Cocos2D 2.X
    Project
  • 假如您要不确信ARC的利,看看就首文章 eight myths about
    ARC 说服你干吗用ARC。

 
 值得注意的是ARC不能够脱所有的内存泄漏。你依然时有发生或内存泄漏,这要可能是出于blocks(块),引用循环,CoreFoundation对象管理差(通常是C结构体,或者是真正充分不好之代码)。

 

2)适当的地方以reuseIdentifier   

   
 在app开发被的一个周边的吧UITableViewCells,UICollectionViewCells,UITableViewHeaderFooterViews设置一个不错的reuseIdentifier(重用标识)。

 

 

   
 为了最大化性能,一个tableView的数据源一般应用UITableViewCell对象,当其当tableView:cellForRowAtIndexPath:中分配数据给cells的时光。一个表视图维护了一个UITableViewCell对象的行或者列表,这些目标都被数据源标记为用。

      如果您绝不reuseIdentifier 会怎么样也?

    
如果你用,你的tableview每显示一行将会晤安排一个新的cell。这是不行麻烦的操作以切会潜移默化您app滚动的特性。

     自从引进了iOS6,你当也header and footer
视图设置reuseIdentifiers,就像以 UICollectionView’s cells 和
supplementary views(补充视图)一样。 

   
 使用reuseIdentifiers,当你的数据源要求提供一个初的cell给tableview的早晚调用这个方 

[cpp] view plain copy

 
  1. NSString *CellIdentifier = @"Cell";  
  2.   
  3. UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];  

 

3)可能的时光装视图为不透明

     如果您闹无透明视图(opaque
views)–也就是说,没有透明度定义之视图,你应有设置他们之opaque属性为YES。 

     为什么?
这会允许系统因为极其帅的不二法门绘制而的views。这是一个简练的特性可以于Interface
Builder 和代码中装置。 

     苹果的文档 Apple
documentation遭起指向斯特性之叙述 

   
 本条特性提供了一个提示给图系统如何对待这视图。如果安也YES,绘制系统将会见管这个视图视为完全不透明。这样允许系统优化一些制图操作和加强性能。如果安也NO,绘图系统会复合这个视图和其余的情,这个特性之默认值是YES

   
在相对静态的屏幕上,设置opaque属性不会见来啊大题材。尽管如此,如果你的视图是放在一个scrollView,或者是一个苛的动画的平有的,不设置是特性绝对会潜移默化您的先后的特性。 

    你啊得使Debug\Color olor Blended Layers选项
在公的模拟器中形象化的见没设置也未透明(opaque)的视图.你的靶子应该是竭尽多之安装视图为透明。 

 

4)  避免臃肿的XIB文件

   
 故事板,由iOS5推介,很快的代XIBs。尽管如此,XIBs在转动静下依然是好有因此之。如果你得以IOS5事先版本的装备上运行或你想从定义重用的视图,那么您实在不可知幸免用其。 

   
 如果您放在心上使用XIBs,那么被其尽量的简要。尝试也一个计算控制器创建一个XIB,如果可能的话,把一个视图控制器的视图分层管理于独立的XIBs中。 

   
注意当你加载一个XIB到内存的时段,它富有的内容还见面载入内存,包括有的图形。如果您有视图但无是使就以,那若便浪费了可贵的内存。值得注意的凡随即不会见起在故事板中,因为故事版就见面当用的时实例化一个视图控制器。 

   
当您载入一个xib,所有的图像文件会给缓存,如果是付出OSX,那么音频文件也会见被缓存。 

    Apple’s
documentation 如是说: 

 
  当您载入一个富含了图及声音资源引用的nib文件时,nib加载代码读取实际的图文件和音频文件到外存中并缓存它。在OS
X中,图片及节奏资源给储存于曾命名的休息存
中如此您可于随后用之时访问它们。在iOS中,只有图片资源给缓存,访问图片,你用NSImage或者UIImage的imageNamed:方法来走访,具体行使在你
的阳台。

   
显然这为发生在使用故事板的当儿。尽管如此,我还免能够找到这种说法之证据。如果你明白,请于自家留言。 

    想上再多关于故事板的再度多内容也?看看Matthijs Hollemans的 Beginning
Storyboards in iOS 5 Part
1and Part
2. 

 

5)不要阻塞主进程

 
  你永远不应以主线程遭遇举行其他繁重的做事。这是因UIKIt的富有工作且当主线程中进行,比如画画,管理触摸,和响应输出。 

您的app的有着工作且在主线程上进行就见面时有发生不通主线程的高风险,你的app会表现的反应迟钝。这是于App
Store里获一星球评论的高效途径!(作者卖萌..) 

   
阻塞主线程最多的动静便是起在您的app进行I/O操作,包括牵扯到其他需要读写外部资源的天职,比如读取磁盘或者网络 

    你可以异步的行网络任务采取NSURLConnection中的此办法: 

[cpp] view
plain copy

 

  1. + (void)sendAsynchronousRequest:(NSURLRequest *)request queue:(NSOperationQueue *)queue completionHandler:(void (^)(NSURLResponse*, NSData*, NSError*))handler  

   
 或者采用第三着框架比如 AFNetworking. 

   
如果你以做另外异常开发的操作(比如执行一个耗时的盘算,或者读写磁盘)使用Grand
Central Dispatch(GCD)或者 NSOperations 和 NSOperationQueues. 

    使用GCD的模板如下代码所示: 

[cpp] view
plain copy

 

  1. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{  
  2.   
  3.     // switch to a background thread and perform your expensive operation  
  4.   
  5.    
  6.   
  7.     dispatch_async(dispatch_get_main_queue(), ^{  
  8.   
  9.         // switch back to the main thread to update your UI  
  10.   
  11.    
  12.   
  13.     });  
  14.   
  15. });  

      这里怎么dispatch_async
嵌套在首先个的中间?这是盖任何UIKit相关的代码都不能不以主线程上推行。 

      对NSOperation和GCD的详情感兴趣?看看Ray
Wenderlich’s Multithreading and Grand Central Dispatch on iOS for
Beginners 教程,和
Soheil Azarpour’s How To Use NSOperations and
NSOperationQueues 教程。 

 

 

6)调整图像视图中的图像尺寸

   
如果您用UIImageView呈现app束中之图时,确认图片和UIImageView的尺码相同。缩放图片会杀之耗时,特别是当你的UIImageView被嵌入UIScrollView。 

   
 如果图片是自从远程服务器上下载的,有时你没法控制图片尺寸,或者你切莫能够在服务器上于下载前缩放它。在这些状况下而可当图片下载完成后手动缩放一不成,最好是在后台进程被。然在UIImageView中使调整尺寸下的图纸。 

 

7)选择正确集合

   
 学着怎么在手头工作负采用最相宜的类或对象是摹写来高效代码的主干。当时所以集合是(collections),这个说法特别对。 

     可喜的凡当苹果开发者文档( Collections Programming
Topics)中来详尽分解可用类之间的涉嫌,还有说各个类的适用情形。这个文档是每个使用集合的总人口之必读文档。 

    这是一个最广泛的聚合类型的神速简介: 

  • Arrays:有序的值的列表,用index快速搜索,通过值查找慢,insert/delete操作慢。 
  • Dictionaries:存储键/值对.用index快速搜索。 
  • Sets: 无序的值列表。通过价值快速搜索,insert/delete快。 

 

8)启用Gzip压缩

   
 大量跟不断提高之app依赖从远端服务器或者外部APIs获取的外表数据。某些时段你或会见开发有需要下载XML,JSON,HTML或者其他文本格式的使用。 

   
 问题是挪装备未克确保网络环境,用户或一分钟当边缘网络,下同样分钟以是3G网络,无论什么动静下,你不思你的用户一直等候。 

   
 一个回落文件大小并加紧下载的网络资源的道是以于您的服务器和客户端上采取GZIP压缩,对于文本数据这种产生高比率压缩的多少吧很实用。 

   
 好信息是iOS早已默认支持GZIP压缩,如果你是运NSURLConnection或者建立以就之上的框架比如AFNetworking。更好之音讯是一切云服务提供商像 Google
App
Engine既发送压缩后的响应数据。 

     这里来同一首文章great article about GZIP
compression 介绍如何以公的Apache或IIS服务器上启用GZIP。 

 

中档性能提升

   
好之,当提到优化你的代码时,你应该十分自信而已初级的法子就完全控制了。但偶尔有些题材之解决措施并无是那么鲜明,它由而app的布局以及代码决定,尽管如此,在对的上下文中,它们或者是尚未价值之。 

9)重用和延期加载视图
   

   
 越多之视图就起逾多之绘图操作,最终表示又多的CPU和内存开销。这说得专程针对而你的app嵌入很多视图在UIScrollView时。

     管理这个的技艺是失去模拟UITableView 和
UICollectionView的行事:不要同浅创有的子视图,而是以需要之时节创建,然后把她们若重用队列中。 

     这样,你唯有需要在视图浮动时安排你的视图,避免昂贵的资源分配开销。 

   
 视图创建的机问题也一律适用于你app的其他地方。试想当您点击一个button时见一个视图的情景。至少有半点种植方式: 

     1.屏幕第一差载入时创造视图并藏它。当您用之上,显示出来。 

     2.得表现的时段同样破创视图并展示她。 

     每种方式都发独家的优缺点 

   
 使用第一种植方式,你吃了重新多内存为自创立起来交她放前您都维持了其的内存,然而,当您点击button的时段,你的app会表现得响应快速为她只待变更视图的可视化属性。 

   
 使用第二种植方法会生相反的功效,在需要之时光创建视图,消耗又不见的内存,但当button被点击时应用会表现得不那么响应快速。 

 

10)缓存,缓存,缓存

 

      在支付以时之一个高大之经验是”Cache what
matters”–也就是说那些不大会改变只是会平凡为看的事物。 

   
 你可知缓存些什么吗?缓存的候选项有长途服务器的应,图片,已算过的值(比如UITableView的行高)。 

      NSURLConnection
根据拍卖的Http头缓存资源及磁盘或者内存中,你还好手动创建一个NSURLRequest值加载缓存过之价。 

     
这里有一致段落很硬的代码,用当另外时刻你用对一个不大会改变的图片创建一个NSURLRequest。 

[cpp] view
plain copy

 

  1. + (NSMutableURLRequest *)imageRequestWithURL:(NSURL *)url {  
  2.   
  3.    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];  
  4.   
  5.   
  6.    request.cachePolicy = NSURLRequestReturnCacheDataElseLoad; // this will make sure the request always returns the cached image  
  7.   
  8.     request.HTTPShouldHandleCookies = NO;  
  9.   
  10.     request.HTTPShouldUsePipelining = YES;  
  11.   
  12.     [request addValue:@”image/*” forHTTPHeaderField:@”Accept”];  
  13.   
  14.     return request;  
  15.   
  16. }  

      如果想了解还多关于Http
caching,NSURLCache,NSURLConnection等情节,请阅读the NSURLCache
entry

     
注意,你可以由此NSURLConnection获取取一个URL请求,AFNetworking也足以。有了这技能这样您不用转任何你的纱代码。 

      如果假定缓存不牵扯到HTTP请求的其它东西,NSCache是那个好的选项。

     
NSCache像NSDictionary,但是当系统要回收内存的时光会自行的移除内容。 

      对HTTP
Cache感兴趣并想模仿还多的情节?推荐阅读这篇稿子best-practices document on
HTTP
caching

 

11)考虑绘图

 
  在IOS中来诸多办法好做有特别棒外观的buttons,你可是由于全尺寸的图像,也得运用调整尺寸下的图像,或者您用CALayer,CoreGraphics,甚至OpenGL手动的其。 

   
当然,每种途径都有不同的复杂度级别与见仁见智之属性,这篇文章很值得一念post
about iOS graphics performance
here,这是Apple
UIKit团队成员Andy
Matuschak发表的章,里面对各种法子来局部可怜深的见地和指向性的权衡。 

   
 使用预渲染图片更快,因为iOS不用创造同张图像及制图图形到屏幕及(图像已经处理好了)。问题是你用任何将这些图片放上应用束里,增加它的尺寸。那便是干什么使用可调动尺寸的图形是那好:你通过移除”浪费了的“图片空间来节省空间。你呢不需要吗不同的因素生成不同之图。(例如
buttons) 

 
  尽管如此,用图形你晤面去代码调整你图的力,需要同不善而平等不善的别它们然后将它在到下中。这是独暂缓的长河。另外一些设您闹动画或者多张稍微变化的图形(例如
颜色叠加),你用加博的图样增加了应用束的深浅。 

   
 总结一下,你要想对您来说无比要害的凡呀:绘图性能还是app的生笑.通常两单还分外关键,所以若会于一个工里采取即时片种植艺术。 

 

12)处理外存警告

     
当系统外存低的时段iOS会通知所有的正在运作的app,关于低内存警告的处理苹果官方文档 official
Apple
documentation描述: 

     
如果你的使用收到此警示,它要尽量多之放走内存。最好的法子是移除对缓存,图像对象,和另外稍后要创造的对象的胜引用。 

      幸运的凡,UIKit提供了部分措施去接低内存警告: 

  • 贯彻App代理中之applicationDidReceiveMemoryWarning:方法。 
  • 重载你从定义UIViewController子类中之didReceiveMemoryWarning方法。 
  • 报接收UIApplicationDidReceiveMemoryWarningNotification的通告 

      一旦接收这些警告,你的拍卖办法要就响应并释放不必要的内存。 

     
举例,如果视图当前不可见,UIViewController的默认行为是破这些视图;子类可以通过免去额外的数据结构来填补父类的默认行为。一个应用程序维护一个图形的缓存,没有当屏幕上的图片都见面为放出。 

   
 一旦接到内存警告,释放或的通内存是十分重大之,否则你就是有深受你的app被系统杀死的的高风险。 

   
 尽管如此,开始扑杀对象释放内存的下要小心,因为您待确保其会当以后再次创设。当您开发app的时节,用而的模拟器上的拟内存警告功能测试这种情形。 

 

13)重用好开对象

   有的对象的初始化非常慢–NSDateFormatter
和 NSCalendar是片只例,但是若莫克幸免用其,当你于 JSON/XML响应中剖析日期时。 

 
 避免下这些目标时的特性瓶颈,试着尽可能的任用这些目标。你得入你的类吃成为一个性质,也可创造为静态变量。 

 
 注意要你选了第二种植办法,这个目标在app运行的时候会一直维系在内存里,像单例一样。 

 
下面就段代码演示了NSDateFomatter作为一个性质之lazy加载,第一次给调用然后创建它,之后就运曾开立以的实例 

[cpp] view
plain copy

 

  1. // in your .h or inside a class extension  
  2.   
  3. @property (nonatomic, strong) NSDateFormatter *formatter;  
  4.   
  5.    
  6. // inside the implementation (.m)  
  7.   
  8. // When you need, just use self.formatter  
  9.   
  10. – (NSDateFormatter *)formatter {  
  11.   
  12.     if (! _formatter) {  
  13.   
  14.         _formatter = [[NSDateFormatter alloc] init];  
  15.   
  16.         _formatter.dateFormat = @”EEE MMM dd HH:mm:ss Z yyyy”; // twitter date format  
  17.   
  18.     }  
  19.   
  20.     return _formatter;  
  21.   
  22. }  

      
同样要切记设置一个NSDateFormatter的日子格式几乎与创建一个新的均等慢。因此,如果以你的使用被你往往需要处理多只日子格式,你的代码应该获利于初始化创建,重用,多个NSDateFormatter对象。 

14) 使用精灵表

   
你是一个游玩开发者也?精灵表是公的好爱人之一.精灵表让绘制比正规屏幕绘制方法还迅速,消耗又不见的内存。 

    这里出星星点点个非常过硬的精灵表使用的教程 

  1. How To Use Animations and Sprite Sheets in
    Cocos2D
  2. How to Create and Optimize Sprite Sheets in Cocos2D with Texture
    Packer and Pixel
    Formats

    第二独学科详细覆盖了像素格式,它可以针对游戏性有一个可衡量的熏陶。 

    如果对精灵表还无是颇熟稔,一个万分好之介绍 SpriteSheets – The Movie,
Part 1and Part
2. 这些视频的撰稿人是Andreas
Löw,一个顶风靡的缔造精灵表的家伙Texture Packer的奠基人。 

   
 除了采用精灵表之外,之前就说交之始末呢得就此当玩耍上.举个例子,如果你的玩耍有许多灵活,比如以规范的大敌要炮弹打游戏,你得选用精灵表额如是每次又创设它们。 

 

15)避免重新处理数量

     很多app调用函数获取远程服务器上的数据.这些多少一般是经过JSON 或者
XML格式来传。非常重大的是以求与接收数据的当儿全力当两岸用同样的数据结构。 

     理由?在内存中操纵数据为适度你的数据结构是甚贵的。 

   
 比如,如果你需要以报表视图中显得数据,最好要和接收数据是屡屡组的格式,以避免任何中间决定数据,使其入您以app中行使的数据结构 

   
 相似之,如果你的应用程序依赖让看特定值的键,那么您恐怕会见想如果呼吁和收一个键/值对之字典 

   
 通过第一不善就拿走科学格式的数额,在融洽的应用程序中您便会见避免多底还处理工作,使数码符合您的取舍的结构。  

 

16)选择对的数格式

    你可以生不少道从web 服务遭遇传递数据到公的app中    

    JSON
是相同种通常比XML小且解析更快之格式,它的传导的内容吧较小。自iOS5自,内置的JSON解析非常好用 built-in
JSON
deserialization

   
尽管如此,XML的一个优势当你使用SAXparsing方法时,你可以传过程中读取它,在面的非常很的数量时,你不要像JSON一样在数额下充斥了后才起读取。 

 

17)适当的安背景图片

    像iOS编码的其他工作一样,至少发生三三两两种植不同方法去替换你视图的背景图片。 

  1. 而可装你的视图的背景颜色为UIColor的colorWithPatternImage创建的水彩。 
  2. 卿可以长一个UIImageView子试图为View 

   
如果你产生全尺寸的背景图片,你绝对要为此UIImageView,因为UIColor的colorWithPatternImage是重的创建小之模式图,在这种情景下用UIImageView方式会节约很多内存。 

[cpp] view
plain copy

 

  1. // You could also achieve the same result in Interface Builder  
  2.   
  3.  UIImageView *backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@”background”]];  
  4.   
  5. [self.view addSubview:backgroundView];  

   
 尽管如此,如果你计划用模式图背景,你应有是故UIColor的colorWithPatternImage。它又快一些,而且这种状态不见面采用多内存。 

[cpp] view
plain copy

 

  1. self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@”background”]];  

18)减少而的网络占用

    UIWebView
是特别游泳的.它非常容易用来展示web内容,甚至创造而app的视窗。这些还是标准UIKit
空间大麻烦做到的。

   
尽管如此,你或注意你得为此在公的app中之UIWebView组件并不曾Apple的Safari
app快。这是Webkit’s的Nitro引擎的限定以。JIT
compilation. 

   
 所以为了获得最佳的性能,你得调你的HTML。第一项事是硬着头皮多的避免Javascript,包括避免大之框架比如jQuery。有时下vanilla
Javascript取代依赖的框架会快很多。 

   
 随时随地以异步加载Javascript文件之实施。特别当它不直接影响到页面表现的上,比如分析脚本。 

   
最后,总是要发现及您于于是底图形,保持图片的不易尺寸。正而斯科目前面所提到的,利用精灵表的优势来节省内存和增长速度。 

     想使博取更多的信,看看WWDC 2012 session #601 – Optimizing Web
Content in UIWebViews and Websites on
iOS. 

 

19) 设置阴影路径

     你待被视图或者layer添加一个阴影,你应当怎么开? 

     大多数开发者是长 QuartzCore框架到工程中,然后形容如下代码: 

[cpp] view
plain copy

 

  1. #import <QuartzCore/QuartzCore.h>  
  2.   
  3.  // Somewhere later …  
  4.   
  5. UIView *view = [[UIView alloc] init];  
  6.   
  7.  // Setup the shadow …  
  8.   
  9. view.layer.shadowOffset = CGSizeMake(-1.0f, 1.0f);  
  10.   
  11. view.layer.shadowRadius = 5.0f;  
  12.   
  13. view.layer.shadowOpacity = 0.6;  

      看起非常简单,是吧? 

     
不好的凡这个主意有一个题目。核心动画必须使优先做一样帐篷动画确定视图具体形象后才渲染阴影,这是怪辛苦的操作。 

      这里有只代表方式给系统重新好之渲染,设置阴影路径: 

[cpp] view
plain copy

 

  1. view.layer.shadowPath = [[UIBezierPath bezierPathWithRect:view.bounds] CGPath];  

     如果你想清楚此情的再次多技巧,Mark Pospesel 写了同样首post
about shadowPath. 
     

   
 设置阴影路径,iOS不需连续计算如何绘制阴影。而是用早已算好之的路。坏消息是它借助与您的视图格式,你是视图可能大为难计算这途径。另一个题材是若待以历次视图的框架改变时更新阴影路径。 

 

20) 优化你的表视图

    表格视图需要快速的滚动,如果不克,用户会方便注意到不可开交落后。 

    为了给您的表视图流畅的滚,保证你兑现了下列的提议。 

  • 通过是的reuseIdentifier重用cells 
  • 尽可能多的设置views 为无透明,包括cell本身。 
  • 避渐变,图像缩放,屏幕外的绘图。 
  • 设若尽胜不连续一样,缓存它们。 
  • 假如cell显示的情出自网络,确保异步和缓存。 
  • 使用shadowPath来起阴影。 
  • 缩减子视图的多寡。 
  • cellForRowAtIndexPath:中做尽量少的行事,如果急需做同之办事,那么单纯做同软并缓存结果。 
  • 运相当的数据结构存储你要的音讯,不同之构造产生对不同的操作发生不同的代价。 
  • 下rowHeight,sectionFooterHeight,sectionHeaderHeight为常数,而无是询问代理。 

 

21) 选择正确的数目存储方

   当要存储和朗诵博大数目的下你的选择是啊? 

   你生出部分挑选,包括: 

  • 运 NSUserDefaults存储它们。 
  • 囤在结构化文件中,XML,JSON,Plist格式中。 
  • 是用NSCoding打包? 
  • 存储在该地数据库,如SQLite 
  • 使用NSData 

   
 NSUserDefaults有啊问题吧?虽然说NSUserDefaults是好而简,它确实十分好只有当你闹十分少的数目而怀(像而的号,或者音量是初步还是拉)。一旦您点很数目,会来双重好的别样选择。 

   
 保存在结构化文件被为说不定产生问题。一般的,在解析之前,你需要加载整个文件及外存中,这是死耗时的操作。你得下SAX去处理XML文件,但是那是一个复杂的作法。同时你加载了整整之目标上内存,其中起若想使的也发无思只要之。 

   
 那么NSCoding怎么样也?不幸的凡,它吗一如既往要读写文件,跟方说的点子发生相同的题材。 

     你太好的化解智是使用SQLite或者 Core Data.
通过这些技巧,你可执行一定的询问才加载需要之目标,避免暴力搜索方法来查找数据。性能方面,SQLite和Core
Data 非常相近。 

    SQLite 和 Core Data最可怜的不等就是其的动方式。Core
Data呈现为一个对象图模型,但是SQLite是一个传统的DBMS(数据库管理体系).通常Apple建议乃用Core
Data,但是只有您产生新鲜的故无吃你而会惦记逃脱它们,使用更低级的SQLite。 

   
如果当公的app中动用SQLite,一个便于之库 FMDB 允许你下SQLite而未用专研SQLite的C
API。 

 

尖端性能技巧

 
 寻找有精英的办法去化十足的代码忍者?这些高档性能技巧可以适度的当儿下让您的app运行得硬着头皮的神速。 

22)加速开动日

 
 App的开行时十分主要,特别是首先不良启动的时候。第一影响表示最多矣! 

 
 最要命之业务是保你的App开始尽心尽力的快,尽量的基本上的实践异步任务,不如网络要,数据库访问,或者数额解析。 

 
 尽量避免臃肿的XIBs,因为若在主线程中加载。但是于故事板中无见面发之题目,所以尽量用它们。 

   Note: 监察人不会见运作而的app在Xcode调试中,
所以确保测试启动性能时断开与Xcode的接连。

 

23)使自动释放池

   
 NSAutoreleasePool负责释放于代码块被之机关释放对象。通常,它是于UIKit自动调用的。但是也发一部分景我们用手动创建NSAutoreleasePools。

   
 举个例子,如果你创造太多的现对象在你的代码中,你晤面小心到您的内存用量会大增直到对象吃保释掉。问题是内存只有在UIKit排空(drains)自动释放池的早晚才能够于放走,这意味着内存为霸占的时间越了亟需。
               

   
 好信息是你可以于您的@autoreleasepool段遭遇创造临时对象来避免上述情况。代码如下所示。

[cpp] view
plain copy

 

  1. NSArray *urls = <# An array of file URLs #>;  
  2. for (NSURL *url in urls) {  
  3.   
  4.     @autoreleasepool {  
  5.   
  6.         NSError *error;  
  7.   
  8.         NSString *fileContents = [NSString stringWithContentsOfURL:url  
  9.   
  10.                                          encoding:NSUTF8StringEncoding error:&error];  
  11.   
  12.         /* Process the string, creating and autoreleasing more objects. */  
  13.   
  14.     }  
  15.   
  16. }  

    在每次迭代下会活动释放具有的靶子。 

    

    你可以阅读更多关于NSAutoreleasePool的始末Apple’s official
documentation.

 

24)缓存图像

     这里出个别栽方式去加载app束中的Image,第一单广大的法子是故imageNamed.
第二只凡是用imageWithContentsOfFile 

     为什么会有些许种植方法,它们有效率为? 

 

     imageNamed 在载入时生缓存的优势。文档 documentation
for imageNamed是这般讲的: 

   
 这个艺术看起在网缓存一个图像对象并指定名字,如果存在则归对象,如果配合图像的目标非以缓存中,这个方法会从指定的公文中加载数据,并缓存它,然后返回结果对象。 

    作为替代,imageWithContendsOfFile 简单的载入图像并无会见缓存。 

    这半单方法的底以身作则片段如下: 

[cpp] view
plain copy

 

  1. UIImage *img = [UIImage imageNamed:@”myImage”]; // caching  
  2.   
  3. // or  
  4. UIImage *img = [UIImage imageWithContentsOfFile:@”myImage”]; // no caching  

 

   
 如果您加载只使用相同不好非常图片,那即便非需缓存。这种情形imageWithContendsOfFile会非常好,这种办法不见面浪费内存来缓存图片。什么时以啊一样种为? 

     然而,imageNamed
对于如选用的图形来说是又好的选择,这种措施节约了时常的打磁盘加载图片的日子。 

 

25) 尽可能避免日期格式化器

 

   
 如果您而用NSDateFormatter来分析日期数,你不怕得小心对待了。之前提到了,尽量的用NSDateFormatters总是一个吓的想法。 

   
 然而,如果你用重快之进度,你可以C代替NSDateFormatter来分析日期。 Sam
Soffes写了千篇一律首 blog post about this
topic来说明什么用代码来分析 ISO-8601日期串。尽管如此,你得十分易的改外的代码例子来适应你的非正规需要。

     噢,听起颇棒,但是你相信有重新好之计呢? 

     如果你能控制而所处理日期的格式,尽可能的选采取 Unix
timestamps。Unix时间戳是简单的平头代表于有起始时间点开到现行的秒数。这个起始点通常是1970年1月1日
UTC 00:00:00。 

    你可以好的管工夫戳转换为NSDate,如下面所示: 

[cpp] view
plain copy

 

  1. – (NSDate*)dateFromUnixTimestamp:(NSTimeInterval)timestamp {  
  2.   
  3.   return [NSDate dateWithTimeIntervalSince1970:timestamp];  
  4.   
  5. }  

     这还比C函数更快

     注意,很多WEB
APIs返回时戳是毫秒,因为当时对javascript最终来利用与拍卖数据是好普遍的。只要记住拿之时刻戳除以1000更传递给dateFromUnixTimestamp方法即可。

25修提高iOS App性能的艺与诀窍

当我们出iOS应用时,好之性对咱们的App来说是死关键的。你的用户也盼望这样,但是要是你的app表现的反射迟钝或好缓慢呢会见误到您的对。 

   
 然而,由于IOS设备的限制有时大为难工作得那个是。我们开发时有很多待我们记住这些善忘的操纵针对性的震慑。 

   
 这是为什么自己写这篇稿子的因。这首文章用备忘录的形式集合了25只技术和诀窍可以就此来增进而的app性能。所以保持阅读来叫你未来之App一个雅不利的提高。 

*   
  Note:在优化代码之前,必须保证发生只需要解决的题目!不要陷入”pre-optimizing(预优化)”你的代码。勤
用Instruments分析你的代码,发现任何一个消加强的地方。Matt
Galloway写了一个动Instruments优化代码的的科目*

*    *

*    以下这些技巧分为三个例外那个的级别—基础,中级,高级。 *

   基础

*  * 这些技巧你若连惦记在实现以您出的App中。 

   1. 之所以ARC去管理内存(Use ARC to Manage Memory)

   2.适用的地方采取reuseIdentifier(Use a reuseIdentifier Where
Appropriate)

   3.尽可能设置视图为免透明(Set View as Opaque When Possible)

   4.幸免臃肿的XIBs文件(Avoid Fat XiBs)

   5.毫无阻塞主进程(Don’t Block the Main Thread)

   6.调整图像视图中之图像尺寸(Size Images to Image Views)

   7.抉择正确集合(Choose the Correct Collection)

   8.启用Gzip压缩(Enable GZIP Compression)

   

*   中级*

*   *这些技术是当您遇到再复杂的景象的时节利用。

    9. 录用和延缓加载视图(Reuse and Lazy Load Views)

   10.缓存,缓存,缓存(Cache,Cache,Cache)

   11.设想绘图(Consider Drawing)

   12.甩卖外存警告(Handle Memory Warnings)

   13.重据此非常开支对象(Reuse Expensive Objects)

   14.采取精灵表(Use Sprite Sheets )

   15.避免重复处理数据(Avoid Re-Processing Data)

   16.挑对的数据格式(Choose the Right Data Format)

   17.适合的安背景图片(Set  Background Images Appropriately)

   18.调减而的大网占用(Reduce Your Web Footprint)  

   19.设置阴影路径(Set the Shadow Path )

   20.而的报表视图Optimize Your Table Views)

   21.抉择对的数量存储方(Choose Correct Data Storage Option)

   

   高级


 *这些技术你当单独以您死积极当它会解决此问题,而且若道之所以她非常舒适的时利用。

   22.增速开动时(Speed up Launch Time )

   23.采用机动释放池(Use AutoRelease Pool)

   24.缓存图像(Cache Images-Or not )

   25.尽可能避免日期格式化器(Avoid Date Formatters Where Possible)  

   没有外的,一起去看看这些技巧吧!

  

 基础的性质提升

1)用ARC去管理内存

   ARC是陪IOS5 一起发布的,它用来祛除周边的底内存泄漏。

   ARC是”Automatic Reference
Counting”的缩写。它自动管理而代码中的retain/release循环,这样你尽管无需手动做这事儿了。

   下面就段代码展示了创一个view的常用代码

 

[cpp] view
plain copy

 

  1. UIView *view =[[UIView alloc] init];  
  2. //…  
  3. [self.view addSubview:view];  
  4. [view release];  

 
 这里太容易忘在代码结束的地方调用release,ARC将会晤自行的,底层的啊你开这些工作。

 
 除了帮忙而乃免内存泄漏,ARC还能够保证对象不再动用时立马被回收来提高而的性。你该当你的工程里大多为此ARC。

   这里是部分念还多关于ARC的好强的资源

  • Apple’s official
    documentation 苹果的官文档。
  • Matthijs Hollemans’s Beginning ARC in iOS
    Tutorial
  • Tony Dahbura’s How To Enable ARC in a Cocos2D 2.X
    Project
  • 万一您要不确信ARC的裨益,看看就首文章 eight myths about
    ARC 说服你为什么用ARC。

 
 值得注意的凡ARC不克去掉所有的内存泄漏。你照样有或内存泄漏,这重要可能是由blocks(块),引用循环,CoreFoundation对象管理不善(通常是C结构体,或者是当真好不好之代码)。

 

2)适当的地方采取reuseIdentifier   

   
 在app开发中之一个广阔的呢UITableViewCells,UICollectionViewCells,UITableViewHeaderFooterViews设置一个没错的reuseIdentifier(重用标识)。

 

 

   
 为了最大化性能,一个tableView的数据源一般应当录取UITableViewCell对象,当它们以tableView:cellForRowAtIndexPath:中分红数据被cells的当儿。一个表视图维护了一个UITableViewCell对象的排或者列表,这些目标都受数据源标记为用。

      如果您绝不reuseIdentifier 会怎么样啊?

    
如果您用,你的tableview每显示一行以会见安排一个簇新的cell。这是殊麻烦的操作而切会潜移默化您app滚动的特性。

     自从引进了iOS6,你当为header and footer
视图设置reuseIdentifiers,就像以 UICollectionView’s cells 和
supplementary views(补充视图)一样。 

   
 使用reuseIdentifiers,当你的数据源要求提供一个初的cell给tableview的早晚调用这个方 

[cpp] view plain copy

 
  1. NSString *CellIdentifier = @"Cell";  
  2.   
  3. UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];  

 

3)可能的时光装视图为不透明

     如果您发出无透明视图(opaque
views)–也就是说,没有透明度定义的视图,你应有设置他们之opaque属性为YES。 

     为什么?
这会允许系统因为极端帅的不二法门绘制而的views。这是一个简短的特性可以以Interface
Builder 和代码中安。 

     苹果的文档 Apple
documentation遭发出对斯特性之讲述 

   
 其一特性提供了一个提醒给图系统如何对待这视图。如果安也YES,绘制系统将见面把这个视图视为完全无透明。这样允许系统优化一些制图操作及加强性能。如果安也NO,绘图系统会复合这个视图和其余的情节,这个特性之默认值是YES

   
在相对静态的屏幕及,设置opaque属性不会见产生啊坏题目。尽管如此,如果你的视图是放置在一个scrollView,或者是一个复杂的卡通的一模一样片,不设置这个特性绝对会影响而的主次的属性。 

    你为堪运用Debug\Color olor Blended Layers选项
在你的模拟器中形象化的见没装为免透明(opaque)的视图.你的对象应该是拼命三郎多的装置视图为透明。 

 

4)  避免臃肿的XIB文件

   
 故事板,由iOS5推荐,很快的代表XIBs。尽管如此,XIBs在瞬间景下仍是坏有因此底。如果你待在IOS5前版本的设备及运行还是您想打定义重用的视图,那么您真正无能够免以她。 

   
 如果你注意使用XIBs,那么被她尽量的简约。尝试吧一个盘算控制器创建一个XIB,如果可能吧,把一个视图控制器的视图分层管理在单独的XIBs中。 

   
注意当你加载一个XIB到内存的时段,它有的情还见面载入内存,包括拥有的图形。如果您生出视图但无是如就以,那您便浪费了可贵的内存。值得注意的凡就不见面时有发生在故事板中,因为故事版就见面在用的时实例化一个视图控制器。 

   
当您载入一个xib,所有的图像文件会被缓存,如果是支付OSX,那么音频文件也会叫缓存。 

    Apple’s
documentation 如是说: 

 
  当您载入一个分包了图与声音资源引用的nib文件时,nib加载代码读取实际的图片文件和音频文件到外存中并缓存它。在OS
X中,图片及拍子资源为贮存于已命名的复苏存
中这样你可于今后需要之早晚看它们。在iOS中,只有图片资源为缓存,访问图片,你采取NSImage或者UIImage的imageNamed:方法来拜访,具体应用在你
的阳台。

   
显然这为发出在运故事板的时节。尽管如此,我还非可知找到这种说法的凭。如果你了解,请让本人留言。 

    想上学再多关于故事板的再次多内容呢?看看Matthijs Hollemans的 Beginning
Storyboards in iOS 5 Part
1and Part
2. 

 

5)不要阻塞主进程

 
  你永远不应有当主线程遭遇开任何繁重的办事。这是为UIKIt的保有工作都在主线程遭遇展开,比如画画,管理触摸,和响应输出。 

而的app的富有工作还于主线程上进行就见面出不通主线程的风险,你的app会表现的反馈迟钝。这是在App
Store里获一星评论的速途径!(作者卖萌..) 

   
阻塞主线程最多之情状就是是发出在公的app进行I/O操作,包括牵扯到另外要读写外部资源的任务,比如读取磁盘或者网络 

    你得异步的实行网络任务采取NSURLConnection中之之方式: 

[cpp] view
plain copy

 

  1. + (void)sendAsynchronousRequest:(NSURLRequest *)request queue:(NSOperationQueue *)queue completionHandler:(void (^)(NSURLResponse*, NSData*, NSError*))handler  

   
 或者使用第三正在框架比如 AFNetworking. 

   
如果您以做其他特别支出的操作(比如执行一个耗时的盘算,或者读写磁盘)使用Grand
Central Dispatch(GCD)或者 NSOperations 和 NSOperationQueues. 

    使用GCD的沙盘如下代码所示: 

[cpp] view
plain copy

 

  1. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{  
  2.   
  3.     // switch to a background thread and perform your expensive operation  
  4.   
  5.    
  6.   
  7.     dispatch_async(dispatch_get_main_queue(), ^{  
  8.   
  9.         // switch back to the main thread to update your UI  
  10.   
  11.    
  12.   
  13.     });  
  14.   
  15. });  

      这里为何dispatch_async
嵌套在率先独之里?这是坐任何UIKit相关的代码都不能不以主线程上实行。 

      对NSOperation和GCD的详情感兴趣?看看Ray
Wenderlich’s Multithreading and Grand Central Dispatch on iOS for
Beginners 教程,和
Soheil Azarpour’s How To Use NSOperations and
NSOperationQueues 教程。 

 

 

6)调整图像视图中之图像尺寸

   
如果你用UIImageView呈现app束中的图形时,确认图片以及UIImageView的尺码相同。缩放图片会大的耗时,特别是当你的UIImageView被嵌入UIScrollView。 

   
 如果图片是自从远程服务器上下载的,有时你没法控制图片尺寸,或者你不克在服务器上以下载前缩放它。在这些情况下你可以以图片下载完成后手动缩放一潮,最好是在后台进程被。然在UIImageView中行使调整尺寸下的图形。 

 

7)选择对集合

   
 学着怎么当手头工作遭到采取最适于的接近或对象是写起快速代码的中坚。当时之所以集合是(collections),这个说法特别对。 

     可喜的是以苹果开发者文档( Collections Programming
Topics)中发生详细解释可用类之间的干,还有说各个类的适用情形。这个文档是每个使用集合的口的必读文档。 

    这是一个极普遍的成团类型的快速简介: 

  • Arrays:有序的价的列表,用index快速搜索,通过值查找慢,insert/delete操作慢。 
  • Dictionaries:存储键/值对.用index快速搜索。 
  • Sets: 无序的值列表。通过价值快速搜索,insert/delete快。 

 

8)启用Gzip压缩

   
 大量暨相连增强的app依赖从远端服务器或者外部APIs获取之表数据。某些时段你恐怕会见付出一些亟待下载XML,JSON,HTML或者其它文本格式的利用。 

   
 问题是动设备不克管网络环境,用户可能一分钟在边缘网络,下一致分钟以是3G网,无论什么情形下,你莫思量你的用户一直等待。 

   
 一个缩减文件大小并加紧下载的大网资源的艺术是同时于您的服务器和客户端上行使GZIP压缩,对于文本数据这种产生胜比率压缩的数码以来十分管用。 

   
 好信息是iOS早已默认支持GZIP压缩,如果您是行使NSURLConnection或者建立在马上之上的框架比如AFNetworking。更好的消息是一切云服务提供商像 Google
App
Engine早已发送压缩后的响应数据。 

     这里出平等篇稿子great article about GZIP
compression 介绍如何当您的Apache或IIS服务器上启用GZIP。 

 

中等性能提升

   
好的,当称到优化你的代码时,你应该怪自信而已经初级的章程就完全控制了。但偶尔有些问题之缓解措施并无是那么鲜明,它由而app的布局以及代码决定,尽管如此,在对的上下文中,它们或者是尚未价值的。 

9)重用和延缓加载视图
   

   
 越多之视图就发出愈来愈多的绘图操作,最终表示又多之CPU和内存开销。这说得特别针对要您的app嵌入很多视图在UIScrollView时。

     管理这个的技艺是失去模拟UITableView 和
UICollectionView的一言一行:不要同坏创有的子视图,而是于用之时节创建,然后拿她们要重用队列中。 

     这样,你才需要在视图浮动时安排你的视图,避免昂贵的资源分配开销。 

   
 视图创建的机遇问题呢一律适用于公app的其他地方。试想当您点击一个button时表现一个视图的场景。至少发生点儿栽方式: 

     1.屏幕第一蹩脚载入时创造视图并隐蔽它。当你要的时,显示出来。 

     2.得表现的下同样坏创视图并出示其。 

     每种艺术都起独家的优缺点 

   
 使用第一种艺术,你吃了又多内存以自创立起来到它释放前您都维持了她的内存,然而,当你点击button的时段,你的app会表现得响应快速为它仅仅需要改变视图的可视化属性。 

   
 使用第二种方式会时有发生相反的效力,在需要之时光创建视图,消耗又不见的内存,但当button被点击时应用会表现得不那么响应快速。 

 

10)缓存,缓存,缓存

 

      在支付以时之一个高大之经验是”Cache what
matters”–也就是说那些不大会改变只是会平凡为看的东西。 

   
 你可知缓存些什么吧?缓存的候选项有长途服务器的应,图片,已算过的价(比如UITableView的行高)。 

      NSURLConnection
根据拍卖的Http头缓存资源及磁盘或者内存中,你还好手动创建一个NSURLRequest值加载缓存过之价值。 

     
这里出雷同段老棒的代码,用在其余时候你用对一个不大会改变之图样创建一个NSURLRequest。 

[cpp] view
plain copy

 

  1. + (NSMutableURLRequest *)imageRequestWithURL:(NSURL *)url {  
  2.   
  3.    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];  
  4.   
  5.   
  6.    request.cachePolicy = NSURLRequestReturnCacheDataElseLoad; // this will make sure the request always returns the cached image  
  7.   
  8.     request.HTTPShouldHandleCookies = NO;  
  9.   
  10.     request.HTTPShouldUsePipelining = YES;  
  11.   
  12.     [request addValue:@”image/*” forHTTPHeaderField:@”Accept”];  
  13.   
  14.     return request;  
  15.   
  16. }  

      如果想了解还多关于Http
caching,NSURLCache,NSURLConnection等情节,请看the NSURLCache
entry

     
注意,你得透过NSURLConnection获取取一个URL请求,AFNetworking也足以。有矣这个技能这样您绝不转任何你的网代码。 

      如果假定缓存不拉到HTTP请求的任何东西,NSCache是老大好的选择。

     
NSCache像NSDictionary,但是当系统要回收内存的早晚会自行的移除内容。 

      对HTTP
Cache感兴趣并想学还多之始末?推荐阅读这篇文章best-practices document on
HTTP
caching

 

11)考虑绘图

 
  在IOS中产生成百上千计可打造有十分过硬外观的buttons,你可以是由全尺寸的图像,也堪下调整尺寸下的图像,或者您用CALayer,CoreGraphics,甚至OpenGL手动的它。 

   
当然,每种途径都发生例外之复杂度级别及见仁见智的性能,这首文章非常值得一读post
about iOS graphics performance
here,这是Apple
UIKit团队成员Andy
Matuschak发表之稿子,里面对各种办法来一部分充分强的理念和针对性性的权。 

   
 使用预渲染图片更快,因为iOS不用创造同摆放图像及制图图形到屏幕及(图像已经处理好了)。问题是您用任何将这些图片放上应用束里,增加她的尺寸。那便是怎使用可调动尺寸的图是那好:你通过移除”浪费了底“图片空间来节省空间。你啊未待也不同的因素生成不同的图。(例如
buttons) 

 
  尽管如此,用图你见面失掉代码调整而图的力量,需要一致糟以平等赖的转它们然后把它进入到使用被。这是只暂缓的历程。另外一些一旦你发动画或者多张稍微变化之图(例如
颜色叠加),你要加以多之图形增加了应用束的尺寸。 

   
 总结一下,你需要想对你的话太要紧之是啊:绘图性能还是app的十分笑.通常两个都格外重点,所以你见面在一个工程里应用就半种艺术。 

 

12)处理外存警告

     
当系统外存低的时段iOS会通知所有的正在运作的app,关于低内存警告的处理苹果官方文档 official
Apple
documentation描述: 

     
如果您的施用收到这警示,它要尽量多之获释内存。最好的章程是移除对缓存,图像对象,和其他稍后要创建的靶子的强引用。 

      幸运的凡,UIKit提供了有法去接低内存警告: 

  • 贯彻App代理中的applicationDidReceiveMemoryWarning:方法。 
  • 重载你从定义UIViewController子类中的didReceiveMemoryWarning方法。 
  • 注册接收UIApplicationDidReceiveMemoryWarningNotification的通 

      一旦接到这些警告,你的处理方法必须及时响应并释放不必要之内存。 

     
举例,如果视图当前不可见,UIViewController的默认行为是免这些视图;子类可以透过消除额外的数据结构来上父类的默认行为。一个应用程序维护一个图纸的缓存,没有在屏幕上之图样都见面叫释放。 

   
 一旦接收内存警告,释放或的全体内存是十分重大的,否则你便生出深受您的app被系统杀死的之风险。 

   
 尽管如此,开始扑杀对象释放内存的下如果小心,因为若待确保她会于其后又创设。当你开发app的时节,用而的模拟器上之仿内存警告功能测试这种情况。 

 

13)重用好出对象

   有的对象的初始化非常慢–NSDateFormatter
和 NSCalendar是片只例证,但是你免能够幸免采取其,当您于 JSON/XML响应中剖析日期时。 

 
 避免以这些目标时之性瓶颈,试着尽可能的用这些目标。你得加入你的接近吃变成一个特性,也得创造为静态变量。 

 
 注意要你挑选了第二种植方式,这个目标在app运行的时刻会直接维系在内存里,像单例一样。 

 
下面这段代码演示了NSDateFomatter作为一个特性的lazy加载,第一次等让调用然后创建它,之后便利用就创造于的实例 

[cpp] view
plain copy

 

  1. // in your .h or inside a class extension  
  2.   
  3. @property (nonatomic, strong) NSDateFormatter *formatter;  
  4.   
  5.    
  6. // inside the implementation (.m)  
  7.   
  8. // When you need, just use self.formatter  
  9.   
  10. – (NSDateFormatter *)formatter {  
  11.   
  12.     if (! _formatter) {  
  13.   
  14.         _formatter = [[NSDateFormatter alloc] init];  
  15.   
  16.         _formatter.dateFormat = @”EEE MMM dd HH:mm:ss Z yyyy”; // twitter date format  
  17.   
  18.     }  
  19.   
  20.     return _formatter;  
  21.   
  22. }  

      
同样如果牢记设置一个NSDateFormatter的日子格式几乎与创建一个新的一样慢。因此,如果在你的运用被君频繁需要处理多个日子格式,你的代码应该获利为初始化创建,重用,多只NSDateFormatter对象。 

14) 使用精灵表

   
你是一个游乐开发者也?精灵表是您的好情人之一.精灵表让绘制比标准屏幕绘制方法重复快速,消耗又不见的内存。 

    这里来些许独雅棒的精灵表使用的教程 

  1. How To Use Animations and Sprite Sheets in
    Cocos2D
  2. How to Create and Optimize Sprite Sheets in Cocos2D with Texture
    Packer and Pixel
    Formats

    第二只科目详细覆盖了如素格式,它可本着戏性有一个可衡量的影响。 

    如果对精灵表还不是老熟稔,一个十分好的介绍 SpriteSheets – The Movie,
Part 1and Part
2. 这些视频的作者是Andreas
Löw,一个极度盛行的创导精灵表的家伙Texture Packer的创建人。 

   
 除了利用精灵表之外,之前都说交之始末吗得就此当玩耍上.举个例子,如果你的娱乐有诸多快,比如以规范的仇要炮弹打游戏,你得选用精灵表额如是历次又创设它们。 

 

15)避免再次处理数量

     很多app调用函数获取远程服务器上的数据.这些数量一般是通过JSON 或者
XML格式来导。非常重大的凡当呼吁和接收数据的上全力在两岸用相同的数据结构。 

     理由?在内存中操纵数据因合适你的数据结构是老高昂之。 

   
 比如,如果你待在表格视图中显示数据,最好请与接收数据是屡组的格式,以避免任何中间决定数据,使其入你当app中采取的数据结构 

   
 相似之,如果您的应用程序依赖让看特定值的键,那么你或会见想只要乞求与收受一个键/值对的字典 

   
 通过第一不行就拿走科学格式的数量,在协调的应用程序中您虽会见避免过多之更处理工作,使数码称您的选取的布局。  

 

16)选择对的多少格式

    你可以出无数智从web 服务受到传递数据到您的app中    

    JSON
是平等种通常比XML小且解析更快之格式,它的传导的内容吗比较小。自iOS5自,内置的JSON解析异常好用 built-in
JSON
deserialization

   
尽管如此,XML的一个优势当你利用SAXparsing方法时,你得传过程遭到读取它,在面的非常坏之多少经常,你不要像JSON一样当多少下充斥了事后才开读取。 

 

17)适当的设置背景图片

    像iOS编码的别样工作一样,至少有些许种植不同方法去替换你视图的背景图片。 

  1. 汝可以安装你的视图的背景颜色为UIColor的colorWithPatternImage创建的水彩。 
  2. 乃可以长一个UIImageView子试图让View 

   
如果你产生全尺寸的背景图片,你绝对要用UIImageView,因为UIColor的colorWithPatternImage是再次的缔造小之模式图,在这种景象下用UIImageView方式会节省很多内存。 

[cpp] view
plain copy

 

  1. // You could also achieve the same result in Interface Builder  
  2.   
  3.  UIImageView *backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@”background”]];  
  4.   
  5. [self.view addSubview:backgroundView];  

   
 尽管如此,如果您计划为此模式图背景,你应有是用UIColor的colorWithPatternImage。它更快有,而且这种情况不见面动群内存。 

[cpp] view
plain copy

 

  1. self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@”background”]];  

18)减少你的纱占用

    UIWebView
是那个游泳之.它非常容易用来展示web内容,甚至创办而app的视窗。这些都是标准UIKit
空间非常为难做到的。

   
尽管如此,你或注意你可就此当你的app中的UIWebView组件并从未Apple的Safari
app快。这是Webkit’s的Nitro引擎的限下。JIT
compilation. 

   
 所以为了获得最佳的性,你待调动你的HTML。第一码事是不择手段多的避免Javascript,包括避免大之框架比如jQuery。有时用vanilla
Javascript取代依赖的框架会快很多。 

   
 随时随地以异步加载Javascript文件之推行。特别当她不直接影响及页面表现的早晚,比如分析脚本。 

   
最后,总是要发现及您以就此之图样,保持图片的没错尺寸。正使之课程前面所波及的,利用精灵表的优势来节省内存和加强速度。 

     想如果取得更多之音讯,看看WWDC 2012 session #601 – Optimizing Web
Content in UIWebViews and Websites on
iOS. 

 

19) 设置阴影路径

     你要让视图或者layer添加一个投影,你该怎么开? 

     大多数开发者是添加 QuartzCore框架到工程被,然后写如下代码: 

[cpp] view
plain copy

 

  1. #import <QuartzCore/QuartzCore.h>  
  2.   
  3.  // Somewhere later …  
  4.   
  5. UIView *view = [[UIView alloc] init];  
  6.   
  7.  // Setup the shadow …  
  8.   
  9. view.layer.shadowOffset = CGSizeMake(-1.0f, 1.0f);  
  10.   
  11. view.layer.shadowRadius = 5.0f;  
  12.   
  13. view.layer.shadowOpacity = 0.6;  

      看起非常简单,是吧? 

     
不好的是者艺术有一个问题。核心动画必须要先期举行一样幕动画确定视图具体形象后才渲染阴影,这是格外辛苦的操作。 

      这里产生个代表方式为系统还好的渲染,设置阴影路径: 

[cpp] view
plain copy

 

  1. view.layer.shadowPath = [[UIBezierPath bezierPathWithRect:view.bounds] CGPath];  

     如果您想了解者情的双重多技巧,Mark Pospesel 写了同样篇post
about shadowPath. 
     

   
 设置阴影路径,iOS不需连续计算如何绘制阴影。而是用已经算好之之路子。坏消息是它凭借以及公的视图格式,你是视图可能非常麻烦计算这路。另一个问题是公用以历次视图的框架改变时更新阴影路径。 

 

20) 优化你的报表视图

    表格视图需要快速的滚,如果非可知,用户会适用注意到死落后。 

    为了让你的报表视图流畅的滚动,保证你实现了下列的建议。 

  • 由此科学的reuseIdentifier重用cells 
  • 尽可能多之装置views 为非透明,包括cell本身。 
  • 避免渐变,图像缩放,屏幕外的绘图。 
  • 万一尽大不连续一样,缓存它们。 
  • 如cell显示的内容出自网络,确保异步和缓存。 
  • 使用shadowPath来起阴影。 
  • 调减子视图的数据。 
  • cellForRowAtIndexPath:中召开尽量少的行事,如果急需做一样之办事,那么单纯做相同潮并缓存结果。 
  • 用相当的数据结构存储你只要之音讯,不同之结构发生于不同的操作有两样之代价。 
  • 下rowHeight,sectionFooterHeight,sectionHeaderHeight为常数,而未是探听代理。 

 

21) 选择对的多少存储方

   当要存储和朗诵博好数量的下你的挑三拣四是呀? 

   你产生部分挑,包括: 

  • 运 NSUserDefaults存储它们。 
  • 仓储于结构化文件中,XML,JSON,Plist格式中。 
  • 是用NSCoding打包? 
  • 存储于地方数据库,如SQLite 
  • 使用NSData 

   
 NSUserDefaults有什么问题啊?虽然说NSUserDefaults是好而简单,它实在怪好只有当您生出深少的多寡如果存(像您的阶段,或者音量是开还是拉)。一旦你点很数目,会生出重复好的外选项。 

   
 保存在结构化文件中也说不定来题目。一般的,在条分缕析之前,你得加载整个文件及内存中,这是很耗时的操作。你得用SAX去处理XML文件,但是那是一个犬牙交错的作法。同时你加载了全套之目标上内存,其中有若想如果的呢有不思要之。 

   
 那么NSCoding怎么样呢?不幸的凡,它也一致要读写文件,跟方说的章程发生相同的题目。 

     你不过好的缓解办法是应用SQLite或者 Core Data.
通过这些技术,你可以实行一定的询问才加载需要的靶子,避免暴力搜索方法来搜寻数据。性能方面,SQLite和Core
Data 非常接近。 

    SQLite 和 Core Data最特别之两样就是是她的利用办法。Core
Data呈现为一个靶图模型,但是SQLite是一个民俗的DBMS(数据库管理体系).通常Apple建议您用Core
Data,但是只有你生出新鲜的缘由不为您乃见面怀念逃脱她,使用还低级的SQLite。 

   
如果在你的app中应用SQLite,一个利于的库 FMDB 允许而以SQLite而未用专研SQLite的C
API。 

 

高档性能技巧

 
 寻找有天才之方去化十足的代码忍者?这些高档性能技巧可当的时候使用让你的app运行得硬着头皮的速。 

22)加速开动日

 
 App的开行时很主要,特别是首先软开行的时。第一影响表示最多矣! 

 
 最充分的业务是确保你的App开始尽心尽力的尽快,尽量的基本上的履行异步任务,不如网络要,数据库访问,或者数解析。 

 
 尽量避免臃肿的XIBs,因为你于主线程中加载。但是当故事板中未见面发之问题,所以尽可能用它。 

   Note: 监察人不见面运行而的app在Xcode调试中,
所以确保测试启动性能时断开与Xcode的接连。

 

23)采用机动释放池

   
 NSAutoreleasePool负责释放在代码块被的活动释放对象。通常,它是叫UIKit自动调用的。但是呢时有发生一些景象我们得手动创建NSAutoreleasePools。

   
 举个例,如果你创造太多的旋对象在公的代码中,你见面注意到您的内存用量会增加直到对象吃放出掉。问题是内存只有在UIKit排空(drains)自动释放池的时刻才能够给放飞,这代表内存为占用的年月超过了用。
               

   
 好信息是公可以以你的@autoreleasepool段遭遇开创临时对象来避免上述情况。代码如下所示。

[cpp] view
plain copy

 

  1. NSArray *urls = <# An array of file URLs #>;  
  2. for (NSURL *url in urls) {  
  3.   
  4.     @autoreleasepool {  
  5.   
  6.         NSError *error;  
  7.   
  8.         NSString *fileContents = [NSString stringWithContentsOfURL:url  
  9.   
  10.                                          encoding:NSUTF8StringEncoding error:&error];  
  11.   
  12.         /* Process the string, creating and autoreleasing more objects. */  
  13.   
  14.     }  
  15.   
  16. }  

    在历次迭代之后会活动释放具有的靶子。 

    

    你可以阅读更多关于NSAutoreleasePool的情Apple’s official
documentation.

 

24)缓存图像

     这里发生有限种办法去加载app束中的Image,第一独泛的道是为此imageNamed.
第二单凡是采取imageWithContentsOfFile 

     为什么会出一定量种植艺术,它们有效率为? 

 

     imageNamed 在载入时发缓存的优势。文档 documentation
for imageNamed凡是这么说明的: 

   
 这个点子看起以系缓存一个图像对象并点名名字,如果有则归对象,如果配合图像的目标不在缓存中,这个方法会从指定的文书被加载数据,并缓存它,然后回到结果对象。 

    作为代表,imageWithContendsOfFile 简单的载入图像并无会见缓存。 

    这点儿个方式的底示范片段如下: 

[cpp] view
plain copy

 

  1. UIImage *img = [UIImage imageNamed:@”myImage”]; // caching  
  2.   
  3. // or  
  4. UIImage *img = [UIImage imageWithContentsOfFile:@”myImage”]; // no caching  

 

   
 如果你加载只以相同浅不行图片,那便不需要缓存。这种场面imageWithContendsOfFile会非常好,这种方法不见面浪费内存来缓存图片。什么时用啊一样栽为? 

     然而,imageNamed
对于如选用的图形来说是又好之取舍,这种措施节约了经常的自磁盘加载图片的辰。 

 

25) 尽可能避免日期格式化器

 

   
 如果你如果用NSDateFormatter来分析日期数,你虽得小心对待了。之前提到了,尽量的重用NSDateFormatters总是一个吓之想法。 

   
 然而,如果您得再次快的进度,你可以应用C代替NSDateFormatter来分析日期。 Sam
Soffes写了同样首 blog post about this
topic来证明什么用代码来分析 ISO-8601日期串。尽管如此,你可非常爱的修改外的代码例子来适应你的独特要求。

     噢,听起格外硬,但是你相信来再次好之法门也? 

     如果您能控制而所拍卖日期的格式,尽可能的挑选采取 Unix
timestamps。Unix时间戳是简单的平头代表从某个起始时间点开至本之秒数。这个起始点通常是1970年1月1日
UTC 00:00:00。 

    你得好的管工夫戳转换为NSDate,如下面所示: 

[cpp] view
plain copy

 

  1. – (NSDate*)dateFromUnixTimestamp:(NSTimeInterval)timestamp {  
  2.   
  3.   return [NSDate dateWithTimeIntervalSince1970:timestamp];  
  4.   
  5. }  

     这竟然比C函数更快

     注意,很多WEB
APIs返回时戳是毫秒,因为当时对于javascript最终来以与处理数据是不行广泛的。只要记住拿这时间戳除以1000再度传递让dateFromUnixTimestamp方法即可。

相关文章