不使用reuseIdentifier的话,每显示一行table view不得不设置全新的cell。这对性能的影响可是相当大的,尤其会使app的滚动体验大打折扣。

  自iOS6起,除了UICollectionView的cells和补充views,你也应该在header和footer views中使用reuseIdentifiers。

  想要使用reuseIdentifiers的话,在一个table view中添加一个新的cell时在data source object中添加这个方法:
 
static NSString *CellIdentifier = @"Cell";
 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

  这个方法把那些已经存在的cell从队列中排除,或者在必要时使用先前注册的nib或者class创造新的cell。如果没有可重用的cell,你也没有注册一个class或者nib的话,这个方法返回nil。

  3.尽量把views设置为透明

  如果你有透明的Views你应该设置它们的opaque属性为YES。

  原因是这会使系统用一个优的方式渲染这些views。这个简单的属性在IB或者代码里都可以设定。

  Apple的文档对于为图片设置透明属性的描述是:

  (opaque)这个属性给渲染系统提供了一个如何处理这个view的提示。如果设为YES, 渲染系统认为这个view是完全不透明的,这使得渲染系统优化一些渲染过程和提高性能。如果设置为NO,渲染系统正常地和其它内容组成这个View。默认值是YES。

  在相对比较静止的画面中,设置这个属性不会有太大影响。然而当这个view嵌在scroll view里边,或者是一个复杂动画的一部分,不设置这个属性的话会在很大程度上影响app的性能。

  你可以在模拟器中用DebugColor Blended Layers选项来发现哪些view没有被设置为opaque。目标是,能设为opaque的全设为opaque!

  4. 避免过于庞大的XIB

  iOS5中加入的Storyboards(分镜)正在快速取代XIB。然而XIB在一些场景中仍然很有用。比如你的app需要适应iOS5之前的设备,或者你有一个自定义的可重用的view,你不可避免地要用到他们。

  如果你不得不XIB的话,使他们尽量简单。尝试为每个Controller配置一个单独的XIB,尽可能把一个View Controller的view层次结构分散到单独的XIB中去。

  需要注意的是,当你加载一个XIB的时候所有内容都被放在了内存里,包括任何图片。如果有一个不会即刻用到的view,你这是在浪费宝贵的内存资源了。Storyboards是另一码事儿了,storyboard仅在需要时实例化一个view controller.

  当家在XIB是,所有图片都被chache,如果你在做OS X开发的话,声音文件也是。Apple在相关文档中的记述是:

  当你加载一个引用了图片或者声音资源的nib时,nib加载代码会把图片和声音文件写进内存。在OS X中,图片和声音资源被缓存在named cache中以便将来用到时获取。在iOS中,仅图片资源会被存进named caches。取决于你所在的平台,使用NSImage 或UIImage 的`imageNamed:`方法来获取图片资源。

  很明显,同样的事情也发生在storyboards中,但我并没有找到任何支持这个结论的文档。如果你了解这个操作,写信给我!

  想要了解更多关于storyboards的内容的话你可以看看 Matthijs Hollemans的Beginning Storyboards in iOS 5 Part 1 和 Part 2

  5. 不要阻塞主线程

  永远不要使主线程承担过多。因为UIKit在主线程上做所有工作,渲染,管理触摸反应,回应输入等都需要在它上面完成。

  一直使用主线程的风险是如果你的代码真的block了主线程,你的app会失去反应。这。。。正是在App Store中拿到一颗星的捷径 :]

  大部分阻碍主进程的情形是你的app在做一些牵涉到读写外部资源的I/O操作,比如存储或者网络。

  你可以使用`NSURLConnection`异步地做网络操作:

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

  或者使用像 AFNetworking这样的框架来异步地做这些操作。

  如果你需要做其它类型的需要耗费巨大资源的操作(比如时间敏感的计算或者存储读写)那用 Grand Central Dispatch,或者 NSOperation 和 NSOperationQueues.

  下面代码是使用GCD的模板
 
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    // switch to a background thread and perform your expensive operation
 
    dispatch_async(dispatch_get_main_queue(), ^{
        // switch back to the main thread to update your UI
 
    });
});