UITableView的优化

来源:互联网 发布:游戏编程入门教程 编辑:程序博客网 时间:2024/06/05 19:24

在IOS开发中, UITableView是最常用到的复杂控件. 使用不难, 但想用好却不容易. 需要考虑到后台数据的设计, tableViewCell的设计和优化, 以及tableView的效率等问题. 
本文主要介绍一下UITableView的常见优化技巧, 主要参考博客:  
VVeboTableViewDemo.

tableView的优化主要思路是: 
1. 异步渲染内容到图片。 
2. 按照滑动速度按需加载内容。 
3. 重写处理网络图片加载。 
4. 缓存一切可缓存的, 用空间换时间.

重用cell

UITableViewCell的重用机制是最常见也是最有效的优化方式之一.  
使用dequeueReusableCellWithIdentifier来实现布局相同的cell的重用, 也可以通过cellForRowAtIndexPath 直接复用某个cell. 如

<code class="hljs objectivec has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">- (<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UITableViewCell</span> *)tableView:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UITableView</span> *)tableView cellForRowAtIndexPath:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSIndexPath</span> *)indexPath{    WeiboTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"cell"</span>];    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (cell == <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">nil</span>) {        cell = [[WeiboTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"cell"</span>];    }    [<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span> drawCell:cell withIndexPath:indexPath];    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> cell;]</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li></ul>

因为cellForRowAtIndexPath方法调用非常频繁,初始化,上下滚动,刷新都要调用. 所以cell的标示声明为静态变量更好。

<code class="hljs objectivec has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSString</span> *cellIdentifier = @“Tracks”;</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

避免cell的重新布局

cell的布局填充等操作比较耗时, 一般可在创建时就布局好. 如可将cell单独放到一个class中WeiboTableViewCell, 重写其initWithStyle方法, 在其中将cell的布局设置完成.  
创建cell完成之后, 调用drawCell往其中填充内容即可, 即将cell的布局及填充分开执行, 且尽量将要填充的data提前准备好.

<code class="hljs objectivec has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">- (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>)drawCell:(WeiboTableViewCell *)cell withIndexPath:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSIndexPath</span> *)indexPath {    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSDictionary</span> *data = [datas objectAtIndex:indexPath<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.row</span>]; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 提前缓存好cell中的内容</span>    cell<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.selectionStyle</span> = UITableViewCellSelectionStyleNone;    [cell clear];    cell<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.data</span> = data;    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (needLoadArr<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.count</span>><span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span> && [needLoadArr indexOfObject:indexPath]==<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSNotFound</span>) {        [cell clear];        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span>;    }    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (scrollToToping) {        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span>;    }    [cell draw];}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li></ul>

提前计算并缓存cell的属性及内容

因UITableView继承自UIScrollView, 因此其布局主要表现为Plain和Grouped两种风格. 需先确定其contentSize及每个cell的位置, 才会将其放进去. 如:

要显示100个cell,而当前屏幕只能显示5个. 则reload的时候,会先调用100次heightForRowAtIndexPath方法, 然后调用5次cellForRowAtIndexPath方法; 滚动屏幕时, 每当cell进入屏幕, 都会调用一次heightForRowAtIndexPath和cellForRowAtIndexPath方法.

  1. cellForRowAtIndexPath和heightForRowAtIndexPath是调用最频繁的方法, 要尽量少地调用这两个方法. 
  2. cell填充与计算布局分离.

    cellForRowAtIndexPath只填充cell,  
    heightForRowAtIndexPath负责计算高度, 将高度等布局缓存到数据源中.

  3. 对于富文本AttributedString等cell中内容, 可提前创建好, 进行数据缓存, 然后需要时直接往cell中填充即可.

  4. 使用estimatedRowHeight来预估高度, 防止浪费时间计算屏幕外边的cell, 如

    self.tableView.estimatedRowHeight = 88.

  5. cell内容的异步加载 
    如web的内容异步加载, 图片配合SDWebImage缓存, 将网络请求结果缓存.

subView的绘制

如果有多个不同风格的cell, 可以给每种cell指定不同的重用标识符. 然后使用dequeue每次将其出列使用即可. 如:

<code class="hljs perl has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">NSString <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">*cellId</span> = [NSString stringWithFormat:<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">@“</span>Cell<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">%d</span><span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">%d</span>”, indexPath.section, indexPath.row]; </code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>
  1. 少用addView给cell动态添加view, 减少创建subview的数量如cell大致布局相同, 则可以只定义一种cell, 在初始化时添加, 通过hidden来控制其中内容的显示. 如有可能, 尽量缓存subview.
  2. 慎用clearColor, 多个view层叠加渲染会消耗更多的时间, 所以尽量不要或者少用透明图层, 因系统将透明层与下面的view混合起来计算颜色, 渲染速度. 所以, 慎重使用clearColor.
  3. 尽量将opaque设为YES, 尽量将subview的opaque设为YES, 避免GPU对cell其中的内容进行绘制. 
  4. 避免无用的CALayer渲染特效.
  5. 需要绘制阴影的时候,通过指定阴影的路径提高效率.
  6. 重载subView的drawRect方法如果定制cell的过程中需要多个小的元素的话,最好直接对要显示的多个项目进行绘制,而非采用添加多个subview.

UITableView的局部更新

我们常用[self.tableView reloadData]来进行tableView中的数据更新. 如果只是更新某个section的话, 可以使用reloadSections等进行局部的更新

<code class="hljs smalltalk has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span>.tableView <span class="hljs-method" style="box-sizing: border-box;">reloadRowsAtIndexPaths:</span><<span class="hljs-array" style="box-sizing: border-box;">#(NSArray *)</span>#> <span class="hljs-method" style="box-sizing: border-box;">withRowAnimation:</span><<span class="hljs-array" style="box-sizing: border-box;">#(UITableViewRowAnimation)</span>#> [<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span>.tableView <span class="hljs-method" style="box-sizing: border-box;">reloadSections:</span>[<span class="hljs-class" style="box-sizing: border-box; color: rgb(102, 0, 102);">NSIndexSet</span> <span class="hljs-method" style="box-sizing: border-box;">indexSetWithIndex:</span><span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>] <span class="hljs-method" style="box-sizing: border-box;">withRowAnimation:</span><span class="hljs-class" style="box-sizing: border-box; color: rgb(102, 0, 102);">UITableViewRowAnimationNone</span>];</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>

tableView的异步绘制

对于复杂的tableView界面, 可考虑异步绘制. 使用dispatch_async和dispatch_sync配合, 将业务逻辑与UI绘制分开. 如:

<code class="hljs objectivec has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//异步绘制</span><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">dispatch_async</span>(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>), ^{        <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">CGRect</span> rect = [_data[@<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"frame"</span>] CGRectValue];        UIGraphicsBeginImageContextWithOptions(rect<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.size</span>, <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">YES</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>);        CGContextRef context = UIGraphicsGetCurrentContext();<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//整个内容的背景</span>        [[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UIColor</span> colorWithRed:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">250</span>/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">255.0</span> green:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">250</span>/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">255.0</span> blue:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">250</span>/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">255.0</span> alpha:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>] set];        CGContextFillRect(context, rect);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//转发内容的背景</span>        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> ([_data valueForKey:@<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"subData"</span>]) {            [[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UIColor</span> colorWithRed:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">243</span>/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">255.0</span> green:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">243</span>/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">255.0</span> blue:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">243</span>/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">255.0</span> alpha:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>] set];            <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">CGRect</span> subFrame = [_data[@<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"subData"</span>][@<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"frame"</span>] CGRectValue];            CGContextFillRect(context, subFrame);            [[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UIColor</span> colorWithRed:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">200</span>/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">255.0</span> green:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">200</span>/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">255.0</span> blue:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">200</span>/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">255.0</span> alpha:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>] set];            CGContextFillRect(context, CGRectMake(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, subFrame<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.origin</span><span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.y</span>, rect<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.size</span><span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.width</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">.5</span>));        }        {    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//名字</span>            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span> leftX = SIZE_GAP_LEFT+SIZE_AVATAR+SIZE_GAP_BIG;            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span> x = leftX;            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span> y = (SIZE_AVATAR-(SIZE_FONT_NAME+SIZE_FONT_SUBTITLE+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">6</span>))/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>-<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>+SIZE_GAP_TOP+SIZE_GAP_SMALL-<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>;            [_data[@<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"name"</span>] drawInContext:context withPosition:CGPointMake(x, y) andFont:FontWithSize(SIZE_FONT_NAME)                             andTextColor:[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UIColor</span> colorWithRed:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">106</span>/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">255.0</span> green:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">140</span>/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">255.0</span> blue:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">181</span>/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">255.0</span> alpha:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>]                                andHeight:rect<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.size</span><span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.height</span>];    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//时间+设备</span>            y += SIZE_FONT_NAME+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>;            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span> fromX = leftX;            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span> size = [UIScreen screenWidth]-leftX;            <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSString</span> *from = [<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSString</span> stringWithFormat:@<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"%@  %@"</span>, _data[@<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"time"</span>], _data[@<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"from"</span>]];            [from drawInContext:context withPosition:CGPointMake(fromX, y) andFont:FontWithSize(SIZE_FONT_SUBTITLE)                   andTextColor:[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UIColor</span> colorWithRed:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">178</span>/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">255.0</span> green:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">178</span>/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">255.0</span> blue:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">178</span>/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">255.0</span> alpha:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>]                      andHeight:rect<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.size</span><span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.height</span> andWidth:size];        }<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//将绘制的内容以图片的形式返回,并调主线程显示</span><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UIImage</span> *temp = UIGraphicsGetImageFromCurrentImageContext();        UIGraphicsEndImageContext();        <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">dispatch_async</span>(dispatch_get_main_queue(), ^{            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (flag==drawColorFlag) {                postBGView<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.frame</span> = rect;                postBGView<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.image</span> = <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">nil</span>;                postBGView<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.image</span> = temp;            }}<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//内容如果是图文混排,就添加View,用CoreText绘制</span>[<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span> drawText];}}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li></ul>

NSTimer在cell中的失效问题

NSTimer在UITableViewCell的重用中会失效, 所以不要将timer添加到cell中. 因在滑动tableView时, timer不会触发时间函数. 因它们使用共同的runloop, 而tableView的滑动阻止了timer的时间函数. 
可以考虑: 
1. 对于显示在cell中的text或其他对象上使用timer. 
2. 并行实现, 主要是设置mode参数:

<code class="hljs objectivec has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">NSTimer* timer = [NSTimer timerWithTimeInterval:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0.005</span> target:<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span> selector:<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">@selector</span>(timerFireMethod:) userInfo:@<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"finishAnimation"</span> repeats:<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">YES</span>];    NSRunLoop *currentRunLoop = [NSRunLoop currentRunLoop];    [currentRunLoop addTimer:timer forMode:NSRunLoopCommonModes];</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>

或者

<code class="hljs objectivec has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">timer = [NSTimer timerWithTimeInterval:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5.0</span> target:<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span> selector:<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">@selector</span>(SendHeartBeat) userInfo:<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">nil</span> repeats:<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">YES</span>]; [[NSRunLoop mainRunLoop] addTimer:heartTimer forMode:NSDefaultRunLoopMode];</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>

优化touch事件传递

把不需要接受touch的view的userInteractionEnabled设为0.

自定义cell的绘制

添加大量控件会导致资源开销很大, 可以考虑直接绘制drawRect. 
这一条暂时还不清楚如何实现, 因此不够详细, 有待进一步补充.

cell的按需加载

从UIScrollView的角度出发, 对cell进行按需加载, 即滚动很快时候, 只加载目标范围内的cell.

<code class="hljs axapta has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (needLoadArr.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">count</span>><span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span> && [needLoadArr indexOfObject:indexPath]==NSNotFound) {    [cell clear]; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span>;}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>

例如: 如果目标行与当前行相差超过指定行数,只在目标滚动范围的前后指定3行加载。

<code class="hljs objectivec has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">- (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>)scrollViewWillEndDragging:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UIScrollView</span> *)scrollView withVelocity:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">CGPoint</span>)velocity targetContentOffset:(inout <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">CGPoint</span> *)targetContentOffset{    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSIndexPath</span> *ip = [<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span> indexPathForRowAtPoint:CGPointMake(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, targetContentOffset->y)];    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSIndexPath</span> *cip = [[<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span> indexPathsForVisibleRows] firstObject];    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSInteger</span> skipCount = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">8</span>;    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (labs(cip<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.row</span>-ip<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.row</span>)>skipCount) {        <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSArray</span> *temp = [<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span> indexPathsForRowsInRect:CGRectMake(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, targetContentOffset->y, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span><span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.width</span>, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span><span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.height</span>)];        <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSMutableArray</span> *arr = [<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSMutableArray</span> arrayWithArray:temp];        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (velocity<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.y</span><<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) {            <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSIndexPath</span> *indexPath = [temp lastObject];            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (indexPath<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.row</span>+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">33</span>) {                [arr addObject:[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSIndexPath</span> indexPathForRow:indexPath<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.row</span>-<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span> inSection:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>]];                [arr addObject:[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSIndexPath</span> indexPathForRow:indexPath<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.row</span>-<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span> inSection:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>]];                [arr addObject:[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSIndexPath</span> indexPathForRow:indexPath<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.row</span>-<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span> inSection:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>]];            }        }        [needLoadArr addObjectsFromArray:arr];    }}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li></ul>

不要实现无用的delegate方法

使用tableView要遵循两个协议, 而我们只需实现必需要的代理方法即可. 

UITableViewDelegate

主要提供cell的展示及样式控制, cell的选择, 指定section的头尾显示, 协助完成cell的排序和删除等功能.

<code class="hljs erlang has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">//<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">_</span>______________________________________________________________________________________________________________// this represents the display <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">and</span> behaviour <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">of</span> the cells.@protocol <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">UITableViewDelegate</span><<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSObject</span>, <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">UIScrollViewDelegate</span>>@optional// <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">Display</span> customization<span class="hljs-pp" style="box-sizing: border-box;">- <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(void)</span>tableView:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">UITableView</span> *)</span>tableView willDisplayCell:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">UITableViewCell</span> *)</span>cell forRowAtIndexPath:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">NSIndexPath</span> *)</span>indexPath;- <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(void)</span>tableView:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">UITableView</span> *)</span>tableView willDisplayHeaderView:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">UIView</span> *)</span>view forSection:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">NSInteger</span>)</span>section NS_AVAILABLE_IOS<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">6</span>_0)</span>;- <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(void)</span>tableView:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">UITableView</span> *)</span>tableView willDisplayFooterView:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">UIView</span> *)</span>view forSection:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">NSInteger</span>)</span>section NS_AVAILABLE_IOS<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">6</span>_0)</span>;- <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(void)</span>tableView:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">UITableView</span> *)</span>tableView didEndDisplayingCell:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">UITableViewCell</span> *)</span>cell forRowAtIndexPath:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">NSIndexPath</span>*)</span>indexPath NS_AVAILABLE_IOS<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">6</span>_0)</span>;- <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(void)</span>tableView:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">UITableView</span> *)</span>tableView didEndDisplayingHeaderView:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">UIView</span> *)</span>view forSection:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">NSInteger</span>)</span>section NS_AVAILABLE_IOS<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">6</span>_0)</span>;- <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(void)</span>tableView:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">UITableView</span> *)</span>tableView didEndDisplayingFooterView:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">UIView</span> *)</span>view forSection:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">NSInteger</span>)</span>section NS_AVAILABLE_IOS<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">6</span>_0)</span>;// Variable height support- <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">CGFloat</span>)</span>tableView:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">UITableView</span> *)</span>tableView heightForRowAtIndexPath:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">NSIndexPath</span> *)</span>indexPath;- <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">CGFloat</span>)</span>tableView:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">UITableView</span> *)</span>tableView heightForHeaderInSection:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">NSInteger</span>)</span>section;- <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">CGFloat</span>)</span>tableView:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">UITableView</span> *)</span>tableView heightForFooterInSection:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">NSInteger</span>)</span>section;// Use the estimatedHeight methods to quickly calcuate guessed values which will allow for fast load times of the table</span>.// <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">If</span> these methods are implemented, the above -table<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">View</span>:height<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">ForXXX</span> calls will be deferred until views are ready to be displayed, so more expensive logic can be placed there.<span class="hljs-pp" style="box-sizing: border-box;">- <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">CGFloat</span>)</span>tableView:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">UITableView</span> *)</span>tableView estimatedHeightForRowAtIndexPath:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">NSIndexPath</span> *)</span>indexPath NS_AVAILABLE_IOS<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">7</span>_0)</span>;- <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">CGFloat</span>)</span>tableView:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">UITableView</span> *)</span>tableView estimatedHeightForHeaderInSection:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">NSInteger</span>)</span>section NS_AVAILABLE_IOS<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">7</span>_0)</span>;- <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">CGFloat</span>)</span>tableView:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">UITableView</span> *)</span>tableView estimatedHeightForFooterInSection:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">NSInteger</span>)</span>section NS_AVAILABLE_IOS<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">7</span>_0)</span>;// Section header & footer information</span>. <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">Views</span> are preferred over title should you decide to provide both<span class="hljs-pp" style="box-sizing: border-box;">- <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">UIView</span> *)</span>tableView:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">UITableView</span> *)</span>tableView viewForHeaderInSection:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">NSInteger</span>)</span>section;   // custom view for header</span>. will be adjusted to default or specified header height<span class="hljs-pp" style="box-sizing: border-box;">- <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">UIView</span> *)</span>tableView:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">UITableView</span> *)</span>tableView viewForFooterInSection:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">NSInteger</span>)</span>section;   // custom view for footer</span>. will be adjusted to default or specified footer height// <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">Accessories</span> (disclosures). <span class="hljs-pp" style="box-sizing: border-box;">- <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">UITableViewCellAccessoryType</span>)</span>tableView:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">UITableView</span> *)</span>tableView accessoryTypeForRowWithIndexPath:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">NSIndexPath</span> *)</span>indexPath NS_DEPRECATED_IOS<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>_0, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>_0)</span>;- <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(void)</span>tableView:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">UITableView</span> *)</span>tableView accessoryButtonTappedForRowWithIndexPath:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">NSIndexPath</span> *)</span>indexPath;// Selection// -tableView:shouldHighlightRowAtIndexPath: is called when a touch comes down on a row</span>. // <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">Returning</span> <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">NO</span> to that message halts the selection process <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">and</span> does <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">not</span> cause the currently selected row to lose its selected look while the touch is down.<span class="hljs-pp" style="box-sizing: border-box;">- <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">BOOL</span>)</span>tableView:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">UITableView</span> *)</span>tableView shouldHighlightRowAtIndexPath:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">NSIndexPath</span> *)</span>indexPath NS_AVAILABLE_IOS<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">6</span>_0)</span>;- <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(void)</span>tableView:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">UITableView</span> *)</span>tableView didHighlightRowAtIndexPath:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">NSIndexPath</span> *)</span>indexPath NS_AVAILABLE_IOS<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">6</span>_0)</span>;- <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(void)</span>tableView:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">UITableView</span> *)</span>tableView didUnhighlightRowAtIndexPath:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">NSIndexPath</span> *)</span>indexPath NS_AVAILABLE_IOS<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">6</span>_0)</span>;// Called before the user changes the selection</span>. <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">Return</span> a new index<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">Path</span>, or nil, to change the proposed selection.<span class="hljs-pp" style="box-sizing: border-box;">- <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">NSIndexPath</span> *)</span>tableView:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">UITableView</span> *)</span>tableView willSelectRowAtIndexPath:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">NSIndexPath</span> *)</span>indexPath;- <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">NSIndexPath</span> *)</span>tableView:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">UITableView</span> *)</span>tableView willDeselectRowAtIndexPath:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">NSIndexPath</span> *)</span>indexPath NS_AVAILABLE_IOS<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>_0)</span>;// Called after the user changes the selection</span>.<span class="hljs-pp" style="box-sizing: border-box;">- <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(void)</span>tableView:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">UITableView</span> *)</span>tableView didSelectRowAtIndexPath:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">NSIndexPath</span> *)</span>indexPath;- <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(void)</span>tableView:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">UITableView</span> *)</span>tableView didDeselectRowAtIndexPath:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">NSIndexPath</span> *)</span>indexPath NS_AVAILABLE_IOS<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>_0)</span>;// Editing// Allows customization of the editingStyle for a particular cell located at 'indexPath'</span>. <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">If</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">not</span> implemented, all editable cells will have <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">UITableViewCellEditingStyleDelete</span> set for them <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">when</span> the table has editing property set to <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">YES</span>.<span class="hljs-pp" style="box-sizing: border-box;">- <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">UITableViewCellEditingStyle</span>)</span>tableView:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">UITableView</span> *)</span>tableView editingStyleForRowAtIndexPath:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">NSIndexPath</span> *)</span>indexPath;- <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">NSString</span> *)</span>tableView:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">UITableView</span> *)</span>tableView titleForDeleteConfirmationButtonForRowAtIndexPath:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">NSIndexPath</span> *)</span>indexPath NS_AVAILABLE_IOS<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>_0)</span>;- <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">NSArray</span> *)</span>tableView:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">UITableView</span> *)</span>tableView editActionsForRowAtIndexPath:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">NSIndexPath</span> *)</span>indexPath NS_AVAILABLE_IOS<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">8</span>_0)</span>; // supercedes -tableView:titleForDeleteConfirmationButtonForRowAtIndexPath: if return value is non-nil// Controls whether the background is indented while editing</span>.  <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">If</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">not</span> implemented, the default is <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">YES</span>.  <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">This</span> is unrelated to the indentation level below.  <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">This</span> method only applies to grouped style table views.<span class="hljs-pp" style="box-sizing: border-box;">- <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">BOOL</span>)</span>tableView:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">UITableView</span> *)</span>tableView shouldIndentWhileEditingRowAtIndexPath:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">NSIndexPath</span> *)</span>indexPath;// The willBegin/didEnd methods are called whenever the 'editing' property is automatically changed by the table <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(allowing insert/delete/move)</span></span>. <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">This</span> is done by a swipe activating a single row<span class="hljs-pp" style="box-sizing: border-box;">- <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(void)</span>tableView:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">UITableView</span>*)</span>tableView willBeginEditingRowAtIndexPath:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">NSIndexPath</span> *)</span>indexPath;- <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(void)</span>tableView:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">UITableView</span>*)</span>tableView didEndEditingRowAtIndexPath:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">NSIndexPath</span> *)</span>indexPath;// Moving/reordering// Allows customization of the target row for a particular row as it is being moved/reordered- <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">NSIndexPath</span> *)</span>tableView:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">UITableView</span> *)</span>tableView targetIndexPathForMoveFromRowAtIndexPath:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">NSIndexPath</span> *)</span>sourceIndexPath toProposedIndexPath:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">NSIndexPath</span> *)</span>proposedDestinationIndexPath;               // Indentation- <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">NSInteger</span>)</span>tableView:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">UITableView</span> *)</span>tableView indentationLevelForRowAtIndexPath:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">NSIndexPath</span> *)</span>indexPath; // return 'depth' of row for hierarchies// Copy/Paste</span>.  <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">All</span> three methods must be implemented by the delegate.<span class="hljs-pp" style="box-sizing: border-box;">- <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">BOOL</span>)</span>tableView:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">UITableView</span> *)</span>tableView shouldShowMenuForRowAtIndexPath:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">NSIndexPath</span> *)</span>indexPath NS_AVAILABLE_IOS<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>_0)</span>;- <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">BOOL</span>)</span>tableView:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">UITableView</span> *)</span>tableView canPerformAction:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">SEL</span>)</span>action forRowAtIndexPath:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">NSIndexPath</span> *)</span>indexPath withSender:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(id)</span>sender NS_AVAILABLE_IOS<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>_0)</span>;- <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(void)</span>tableView:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">UITableView</span> *)</span>tableView performAction:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">SEL</span>)</span>action forRowAtIndexPath:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-variable" style="box-sizing: border-box;">NSIndexPath</span> *)</span>indexPath withSender:<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(id)</span>sender NS_AVAILABLE_IOS<span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>_0)</span>;@end</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li><li style="box-sizing: border-box; padding: 0px 5px;">71</li><li style="box-sizing: border-box; padding: 0px 5px;">72</li><li style="box-sizing: border-box; padding: 0px 5px;">73</li><li style="box-sizing: border-box; padding: 0px 5px;">74</li><li style="box-sizing: border-box; padding: 0px 5px;">75</li><li style="box-sizing: border-box; padding: 0px 5px;">76</li><li style="box-sizing: border-box; padding: 0px 5px;">77</li><li style="box-sizing: border-box; padding: 0px 5px;">78</li><li style="box-sizing: border-box; padding: 0px 5px;">79</li><li style="box-sizing: border-box; padding: 0px 5px;">80</li><li style="box-sizing: border-box; padding: 0px 5px;">81</li><li style="box-sizing: border-box; padding: 0px 5px;">82</li><li style="box-sizing: border-box; padding: 0px 5px;">83</li></ul>

以上有非常多的方法, 用于cell属性的控制, 显示风格等.  
除了必要的几个, heightForRowAtIndexPath, viewForHeaderInSection, didSelectRowAtIndexPath之外, 如无特殊要求, 可尽量避免实现, 以免耗时.

UITableViewDataSource

为UITableView提供显示用的数据, 指定cell的操作类型, 并根据操作及进行相应的数据更新操作. 如数据异常, 则可能导致crash.

<code class="hljs objectivec has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//_______________________________________________________________________________________________________________</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// this protocol represents the data model object. as such, it supplies no information about appearance (including the cells)</span><span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">@protocol</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">UITableViewDataSource</span><<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">NSObject</span>></span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">@required</span>- (<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSInteger</span>)tableView:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UITableView</span> *)tableView numberOfRowsInSection:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSInteger</span>)section;<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Row display. Implementers should *always* try to reuse cells by setting each cell's reuseIdentifier and querying for available reusable cells with dequeueReusableCellWithIdentifier:</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Cell gets various attributes set automatically based on table (separators) and data source (accessory views, editing controls)</span>- (<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UITableViewCell</span> *)tableView:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UITableView</span> *)tableView cellForRowAtIndexPath:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSIndexPath</span> *)indexPath;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">@optional</span>- (<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSInteger</span>)numberOfSectionsInTableView:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UITableView</span> *)tableView;              <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Default is 1 if not implemented</span>- (<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSString</span> *)tableView:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UITableView</span> *)tableView titleForHeaderInSection:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSInteger</span>)section;    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// fixed font style. use custom view (UILabel) if you want something different</span>- (<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSString</span> *)tableView:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UITableView</span> *)tableView titleForFooterInSection:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSInteger</span>)section;<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Editing</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Individual rows can opt out of having the -editing property set for them. If not implemented, all rows are assumed to be editable.</span>- (<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">BOOL</span>)tableView:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UITableView</span> *)tableView canEditRowAtIndexPath:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSIndexPath</span> *)indexPath;<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Moving/reordering</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Allows the reorder accessory view to optionally be shown for a particular row. By default, the reorder control will be shown only if the datasource implements -tableView:moveRowAtIndexPath:toIndexPath:</span>- (<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">BOOL</span>)tableView:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UITableView</span> *)tableView canMoveRowAtIndexPath:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSIndexPath</span> *)indexPath;<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Index</span>- (<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSArray</span> *)sectionIndexTitlesForTableView:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UITableView</span> *)tableView;                                                    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// return list of section titles to display in section index view (e.g. "ABCD...Z#")</span>- (<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSInteger</span>)tableView:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UITableView</span> *)tableView sectionForSectionIndexTitle:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSString</span> *)title atIndex:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSInteger</span>)index;  <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// tell table which section corresponds to section title/index (e.g. "B",1))</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Data manipulation - insert and delete support</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// After a row has the minus or plus button invoked (based on the UITableViewCellEditingStyle for the cell), the dataSource must commit the change</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Not called for edit actions using UITableViewRowAction - the action's handler will be invoked instead</span>- (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>)tableView:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UITableView</span> *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSIndexPath</span> *)indexPath;<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Data manipulation - reorder / moving support</span>- (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>)tableView:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UITableView</span> *)tableView moveRowAtIndexPath:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSIndexPath</span> *)sourceIndexPath toIndexPath:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSIndexPath</span> *)destinationIndexPath;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">@end</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li></ul>

常见的方法:  
numberOfRowsInSection, cellForRowAtIndexPath, commitEditingStyle等.

另外,最近看了一篇大牛的文章,对这个问题又做了其他的一些建议。

Tip#1 学习怎么提升速度


我可以写一整篇关于Instruments的文章。在这儿我将给你一个大致的介绍因为这会很有帮助的。


如果你对于Instruments不是很有经验,我劝你周末花些时间来研究一些。当你想要测量内存与时间消耗,他们会帮你很大的忙。然而当你着手做一个app你将会在开发过程中遇到很多问题,代码会变得越来越糟,这时你可能还无暇顾及性能的问题。但是重构是潜在的。为了合适的重构你应该花费精力在分析性能上面。


所以,下面是周末探索内容:


1.打开你的项目并点击Product>Profile

2.在那儿选择Custom

3.找到添加按钮并且添加工具:Allocations,Time,Profile,Leaks

4.观察你的应用,以及他的表现。


例如,我们关心的是速度(但是内存也是一个大问题)。我们需要哪个工具呢?如果你选择Time Profile那你就对了。让我们打开它并观察下运行中的app。



下面你就能看到我们的app的概况。你所看到的就是我打开app并且尽我可能快的上下滚动tableview。这就模拟出了一个很好的“最坏情况假设”,然后我们就可以采取行动了。




这个区域就是我开始滚动app时会执行的代码,我们只想知道在这个区域的时间消耗。




现在你可以开始研究我们上面讨论的代码了。双击这些行中的任何一行(最好是最上面一行,那就是时间被消耗最多的地方)


需要指出很重要的一点,那就是Call Tree下面的选项不是为你在Instruments加载时设置的。你需要自己去设置。


Tip#2 避免阻塞主线程


在这个例子中你会看到第一个图片相关的方法在数据下载并转换成图片对象时阻塞了主线程。你要尽量避免阻塞主线程,这对于collection中的交互对象尤为重要。网络请求?保持他们在后台运行(异步的)并且缓存传回的响应。你肯定不想重复处理任何操作。想象你的cell在一段沉默时间内被绘制。你的cell应该只展示已经保存在你的设备上的数据。这会使你感觉更好的。


Tip#3 重用cells


如果你已经花了一些时间学习iOS,那么不好意思 。这条建议是给那些新接触iOS的同学的。你应该使用dequeueReusableCellWithIdentifier 这个方法去获取一个table或者collection上面的cell。如果你不是这样做的,你就浪费了一段无意义的时间和数据。


Tip#4 缓存下载的图片


这肯定是你在这里读到的最重要的一条建议了。如果你不缓存图片你将会遇到很大的问题。


如果你重用本地的图片那么请使用UIImage的方法imageNamed:。以JPG格式请求图片将会节省时间和资源。如果你是从服务端获取图片那么你就可以获取所需要的那些图片( If you’re getting your image from a server you have the luxury of sending the exact image that’s needed.)。 PNG文件在内存中会占用很大一部分空间。如果你对此感觉好奇你可以在示例中将JPG换成PNG来下载一系列的PNG图片。


使用 SDWebImage 或者 Heneke 来管理图片。在提供的示例中我就是用的 Heneke,在那之前我没有听说过它也没有听说过它的好用之处。


Tip#5 使用富文本标签代价是很昂贵的


费尽周折用富文本标签,代价太昂贵了。尽可能地避免使用这个。问问你自己是否真的需要这个。如果是的话,尽可能的做缓存。


Tip#6 cell高度计算


如果你的table有复杂的动态高度那么你需要缓存计算的高度。考虑多久计算一次(尤其是对于collection views来说),你希望这些高度都是直接可用的。


Tip#7 NsDateFormatter 的痛苦


就像富文本,如果你频繁地初始化,date formatter可以引起大量的内存消耗。比较理想的是你的web端为你提供可读的文字(比起在最后的时间计算要容易很多)。如果没有的话你可以创建一个NSDateFormatter的单例来使用。NSDateFormatter不是线程安全的,但是iOS7以及之后就不再是这样了。多谢quellish提醒我这一点。


Tip#8 透明度


如果你能避免的话你创建的对象最好是不透明的(非透明的,你不能透过它看过去)。如果你有透明的图片,系统必要要很努力地重绘这些图片。实际上你可以在模拟器中通过点击Debug>Clolor Blended Areas来看这些区域的问题。



看到红色的了么,那就意味着这些区域是透明的。当你在跟一个Collectionview打交道时这将是非常耗时。理想的,你想看到整个屏幕都是绿色的。对于你的设计来说那可能是不可行的,但是力求减少你看到的红色的数量。在示例中你可以看到label延伸到了view的尾部,可以被清除掉。


Tip#9 不要过多使用Xib(如果可以的话使用storyboard)


如果要使用xib就要小心一点。当你加载一个Xib,整个的内容会被加载到内存中(图片,隐藏的views)。但是这在storyboard中不会发生他只会实例化当前要用的东西。


有一些特殊的场景下使用xib很有意义。比如你可能会要使用一些第三方的框架而他们采用纯代码的方式来写collection的UI部分。如果你想用xib来创建一个原型cell你可以用xib来做。只是要小心不要过载。


Tip#10 使用CoreGraphics


我很少需要这个,但是当你需要的时候你可以用。使用CoreGraphics并在一个view的drawRect的方法中写你的UI代码。


挑战


谁不喜欢一个好的挑战?让我们在这儿来把它保持下来。这周花时间来做下面两件事。


  • 学习怎么使用Instruments(time profiler, allocations)

  • 通过测试图片缓存(关掉,打开,观察)来检查学习Instruments使用的情况。


https://github.com/mcgraw/dojo-table-performance


Takeaway


在iOS中界面的交互很重要。这是不可妥协的。如果你不花时间在稳固你的应用在设备上的体验,那么人们可能就会离你很远。当我回顾应用中的内容时应用应该是顺畅的。


轮到你了


对于提升性能你的首要建议是什么?我很乐意听取你的建议。请您有空的时候在下面分享。


0 0
原创粉丝点击