tableview用法 tableview如何优化,tableview的优化

如何优化UITableView性能
【tableview用法 tableview如何优化,tableview的优化】几乎在自己所有的应用中都可以看到,可见其重要性 。在使用UITableView时,我们经常会遇到性能问题,一般表现在滚动时比较卡片,尤其是表格单元格包含图片时 。其实只要有针对性的优化,这种问题是不会存在的 。有兴趣可以看看LazyTableImages,官方的示例程序 。虽然你必须从网上下载图片并展示它们,但你不需要 。滚动时不要卡住 。首先,让& # 039;让我们来谈谈虚拟视图的原理 。有兴趣的可以看看《About Table Views in iOS-Based Applications》 。UITableView是UIScrollView的子类,所以可以自动响应滚动事件(一般是上下滚动) 。它包含0到多个UITableViewCell对象,每个表格单元格显示自己的内容 。当需要显示新的单元格时,将调用table view:cellforrowatdinexpath:方法获取或创建单元格;当它看不见的时候,它会再次被释放 。可以看出,同一时间只需要一屏的单元格对象,不需要为每一行创建一个单元格 。此外,UITableView可以分为多个部分,每个部分都可以有自己的头、脚和单元格 。当定位一个单元格时,您需要两个字段:它在哪个部分和它在哪个行 。这在iOS SDK中用NSIndexPath表示,UIKit增加了indexPathForRow:inSection: this创建方法 。编辑之类的其他事情就不提了,因为和本文无关 。介绍完原理,让& # 039;让我们开始优化 。使用不透明视图 。不透明视图可以大大提高渲染速度 。因此,如果不需要,可以将表格单元格及其子视图的不透明属性设置为“是”(默认值) 。的特例包括背景色,其alpha值应为1(例如,don & # 039t使用clear color);图像的alpha值也应该是1,或者在绘制时设置为不透明 。唐& # 039;不要重复创建不必要的表格单元格 。如前所述,UITableView只需要一个UITableViewCell对象的屏幕 。所以当单元格不可见的时候,可以缓存,需要的时候可以继续使用 。而UITableView也提供了这个机制,只需设置一个标识符:static ns string * cell identifier=@ & # 039;XXX & # 039;UITableViewCell * cell=[table view dequeuereusablecellwithcidentifier:cell identifier];if(cell==nil){ cell=[[UITableViewCell alloc]init with style:UITableViewCell style default reuse identifier:cell identifier]auto release];}值得一提的是,当单元格被重用时,其内部绘制的内容不会被自动清除,因此您可能需要调用setNeedsDisplayInRect:或setNeedsDisplay方法 。减少视图的数量 。UITableViewCell还可以进行个人定制 。每个单元格可以包含多个子视图,如Label和ImageView,您还可以自定义一些视图,并将它们放入其contentView中 。这里需要指出的是,view是一个大对象,创建它会消耗大量内存,也会影响渲染效果 。如果您的表格单元格包含大量图片,使用默认的UITableViewCell将极大地影响性能 。奇怪的是,使用自定义视图显然比使用预定义视图更快 。当然,最好的解决方案是继承UITableViewCell,在它的drawRect中自己画:-(void)drawRect:(cgrect)rect { if(image){[image draw at point:image point];self.image=nil} else {[placeHolder draw at point:image point];}[text drawin rect:text rect with font:font line break mode:uilinebreakmodetailstruncation];}但这样一来,你会发现选中一行后,这个单元格会变成蓝色,其内容会被屏蔽 。最简单的方法是将cell的selectionStyle属性设置为UITableViewCellSelectionStyleOne,这样就不会突出显示 。此外,您可以创建一个CALayer,在图层上绘制内容,然后在单元格的contentView.layer上调用addSublayer:方法 。在这个例子中,图层不会显著影响性能,但是如果图层是透明的,或者有圆角、变形等效果,就会影响绘制速度 。可以在以下预渲染图像中找到解决方案 。唐& # 039;不要做额外的绘图工作 。
当实现drawRect:时,其Rect参数是需要绘制的区域,该区域以外的区域不需要绘制 。例如,在上面的示例中,可以使用CGRectIntersectsRect、CGRectIntersection或CGRectContainsRect来确定是否需要绘制图像和文本,然后调用drawing方法 。预渲染图像 。你会发现,即使你做到了以上几点,当新的图像出现时,还是会有短暂的停顿 。解决方法是在位图上下文中绘制一次,导出到UIImage对象,然后绘制到屏幕上 。详情见《利用预渲染加速iOS设备的图像显示》 。唐& # 039;不要阻塞主线程 。完成前几点后,你的表格视图应该可以足够平滑地滚动,但是你可能仍然会让用户感到不舒服 。一个常见的现象是,在更新数据时,整个界面都卡死了,完全不响应用户请求 。出现这种现象的原因是主线程执行一个函数或方法需要很长时间,它可以& # 039;t绘制屏幕并响应用户& # 039;在它完成之前 。最常见的是网络请求,通常需要几秒钟,你不应该& # 039;不要让用户等太久 。解决方案是使用多线程,让子线程执行这些函数或方法 。还有一个知识是,当下载线程数超过2时,会显著影响主线程的性能 。因此,在使用ASIHTTPRequest时,可以使用NSOperationQueue来维护下载请求,并将其maxConcurrentOperationCount设置为2 。而NSURLRequest可以用GCD实现,或者可以使用NSURLConnection的setDelegateQueue:方法 。当然,当你不& # 039;t不需要响应用户请求,还可以增加下载线程数来加快下载速度:-(void)scrollviewdidendrawing:(UIscrollview *)scrollview将决定:(bool)决定{if(!减速){ queue . maxconcurrentoperationcount=5;} }-(void)scrollviewdidenddurring:(UIScrollView *)scroll view { queue . maxconcurrentoperationcount=5;}-(void)scrollViewWillBeginDragging:(ui scrollView *)scroll view { queue . maxconcurrentoperationcount=2;}此外,更新数据的自动加载也很人性化,减少了用户等待下载的时间 。比如每次加载50条信息,滚动到第10个底部可以加载更多的信息:-(void)table view:(UITableView *)table view WillDisplayCell:(UITableViewCell *)Cell for rowatendexpath:(nsindexpath *)Indexpath { if(count-Indexpath . row 10!正在更新){正在更新=是;【自我更新】;} }//update方法得到结果后,还需要注意的是,图片下载时,如果单元格可见,则需要更新图片:nsarray * index paths=[self . table view indexpathsforvisiblerows];for(index paths中的NSIndexPath * visible index path){ if(index path==visible index path){ MyTableViewCell * cell=(MyTableViewCell *)[self . table view cell for rowatindexpath:index path];cell.image=image[cell setNeedsDisplayInRect:imageRect];打破;} }//唐& # 039;不遍历它,只对比头尾,看是否在中间 。最后是上面提到的insertrowatindexpaths:withrowanimation:方法 。插入新行需要在主线程中执行,而一次插入多行(比如50行)会阻塞主线程很长时间 。如果将它更改为reloadData方法,它将被立即处理 。
UITableView的复用机制以及优化
如何优化tableview的使用
使用不透明视图 。不透明视图可以大大提高渲染速度 。因此,如果不需要,可以将表格单元格及其子视图的不透明属性设置为“是”(默认值) 。的特例包括背景色,其alpha值应为1(例如,don & # 039t使用clear color);图像的alpha值也应该是1,或者在绘制时设置为不透明 。不要重复创建不必要的表格单元格 。如前所述,UITableView只需要一个UITableViewCell对象的屏幕 。所以当单元格不可见的时候,可以缓存,需要的时候可以继续使用 。而UITableView也提供了这个机制,只需设置一个标识符:static ns string * cell identifier=@ & # 039;XXX & # 039;UITableViewCell * cell=[table view dequeuereusablecellwithcidentifier:cell identifier];if(cell==nil){ cell=[[UITableViewCell alloc]init with style:UITableViewCell style default reuse identifier:cell identifier]auto release];}值得一提的是,当单元格被重用时,其内部绘制的内容不会被自动清除,因此您可能需要调用setNeedsDisplayInRect:或setNeedsDisplay方法 。另外,在添加表格单元格时,如果你不& # 039;不需要动画效果,它& # 039;最好不要使用insertrow indexes:with row animation:方法,而是直接调用reloadData方法 。因为前者会在所有indexpath上调用table view:cellforrowatdinexpath:方法,即使单元格没有& # 039;不需要展示(我不需要& # 039;我不知道它是否& # 039;这是一个错误),它可能会创建许多冗余单元 。勘误:只在模拟器上测试,真机调试时没有这种bug 。减少视图的数量 。UITableviewCell包括textLabel、detailTextLabel、imageView等视图,还可以自定义一些视图,放入它的contentView中 。但是,视图是一个大对象,创建它会消耗更多的资源,也会影响渲染的性能 。如果您的表格单元格包含大量图片,使用默认的UITableViewCell将极大地影响性能 。奇怪的是,使用自定义视图显然比使用预定义视图更快 。当然,最好的解决方案是继承UITableViewCell,在它的drawRect中自己画:-(void)drawRect:(cgrect)rect { if(image){[image draw at point:image point];self.image=nil} else {[placeHolder draw at point:image point];}[text drawin rect:text rect with font:font line break mode:uilinebreakmodetailstruncation];}但这样一来,你会发现选中一行后,这个单元格会变成蓝色,其内容会被屏蔽 。最简单的方法是将cell的selectionStyle属性设置为UITableViewCellSelectionStyleOne,这样就不会突出显示 。此外,您可以创建一个CALayer,在图层上绘制内容,然后在单元格的contentView.layer上调用addSublayer:方法 。在这个例子中,图层不会显著影响性能,但是如果图层是透明的,或者有圆角、变形等效果,就会影响绘制速度 。可以在以下预渲染图像中找到解决方案 。唐& # 039;不要做额外的绘图工作 。当实现drawRect:时,其Rect参数是需要绘制的区域,该区域以外的区域不需要绘制 。例如,在上面的示例中,可以使用CGRectIntersectsRect、CGRectIntersection或CGRectContainsRect来确定是否需要绘制图像和文本,然后调用drawing方法 。预渲染图像 。你会发现,即使你做到了以上几点,当新的图像出现时,还是会有短暂的停顿 。解决方法是在位图上下文中绘制一次,导出到UIImage对象,然后绘制到屏幕上 。详情见《利用预渲染加速iOS设备的图像显示》 。唐& # 039;不要阻塞主线程 。完成前几点后,你的表格视图应该可以足够平滑地滚动,但是你可能仍然会让用户感到不舒服 。一个常见的现象是,在更新数据时,整个界面都卡死了,完全不响应用户请求 。出现这种现象的原因是主线程执行一个函数或方法需要很长时间,它可以& # 039;t绘制屏幕并响应用户& # 039;在它完成之前 。最常见的是网络请求,通常需要几秒钟,你不应该& # 039;不要让用户等太久 。
解决方案是使用多线程,让子线程执行这些函数或方法 。还有一个知识是,当下载线程数超过2时,会显著影响主线程的性能 。因此,在使用ASIHTTPRequest时,可以使用NSOperationQueue来维护下载请求,并将其maxConcurrentOperationCount设置为2 。而NSURLRequest可以用G C D实现,或者使用NSURLConnection的setDelegateQueue:方法 。当然,当你不& # 039;t不需要响应用户请求,还可以增加下载线程数来加快下载速度:-(void)scrollviewdidendrawing:(UIscrollview *)scrollview将决定:(bool)决定{if(!减速){ queue . maxconcurrentoperationcount=5;} }-(void)scrollviewdidenddurring:(UIScrollView *)scroll view { queue . maxconcurrentoperationcount=5;}-(void)scrollViewWillBeginDragging:(ui scrollView *)scroll view { queue . maxconcurrentoperationcount=2;}此外,更新数据的自动加载也很人性化,减少了用户等待下载的时间 。比如每次加载50条信息,滚动到第10个底部可以加载更多的信息:-(void)table view:(UITableView *)table view WillDisplayCell:(UITableViewCell *)Cell for rowatendexpath:(nsindexpath *)Indexpath { if(count-Indexpath . row 10!正在更新){正在更新=是;【自我更新】;} }//update方法得到结果后,还需要注意的是,图片下载时,如果单元格可见,则需要更新图片:nsarray * index paths=[self . table view indexpathsforvisiblerows];for(index paths中的NSIndexPath * visible index path){ if(index path==visible index path){ MyTableViewCell * cell=(MyTableViewCell *)[self . table view cell for rowatindexpath:index path];cell.image=image[cell setNeedsDisplayInRect:imageRect];打破;} }//唐& # 039;不遍历它,只对比头尾,看是否在中间 。最后是上面提到的insertrowatindexpaths:withrowanimation:方法 。插入新行需要在主线程中执行,而一次插入多行(比如50行)会阻塞主线程很长时间 。如果将它更改为reloadData方法,它将被立即处理 。那& # 039;所有,我认为& # 039;大约是这样 。其他人需要剖析自己,找出瓶颈进行优化 。

tableview用法 tableview如何优化,tableview的优化

文章插图
如何优化QTableView的性能
1.手动设置定长头数据 。举个例子,如果表头可能出现的数据是1到100000,那么我们就以最长的为准,长度不够的就填空 。这样就不需要设置适配,瞬间就能完成表格刷新和切换 。但是代价就是表头难看,数据少的时候有大量的空白 。2.使用当前最大的头数据,只用QFontMetrics计算这个数据的宽度,然后在头上设置fixedWidth() 。这在理论上是可行的,但在实践中是丑陋的 。调整宽度后多余的部分只是QWidget的背景色,没有绘制文字信息,导致页眉文字显示不完整,页眉效果绘制错误 。然后,在尝试搜索关键字& # 039;QTableView垂直标题宽度& # 039;在Qt论坛找到一个帖子,给了我一个清脑的解决方法:3354 。设置标题宽度后,将第一列的宽度设置为0,然后重置 。代码如下:UI-table view-vertical header()-设置固定宽度(width);width=ui-table view-column width(0);ui-tableView-setColumnWidth(0,0);ui-tableView-setColumnWidth(0,width);上述代码将导致表格布局改变,从而触发表格的全局重绘 。在这次重绘中,重新设置宽度后的页眉也可以正常显示 。因为不是所有的列和标题都被设置为自适应的,所以这种重绘是非常有效的 。最终的简档结果如下:-设置自适应后,表格刷新需要10ms 。但是,再次适配割台大约需要10s 。-关闭自适应,手动设置fixedWidth适配报头,刷新数据适配报头,总时间不会超过20ms 。
TableView 加载图片优化(滑动不加载图片思路)
目的:解决滑动加载图片导致卡顿现象 。1.使用scorllView的代理方法优化UIScrollView的两个代理方法,在这两个方法中调用给imageView赋值的方法,可以避免UITableView在滑动加载图片时滚动的问题 。2.在UIScrollView中滑动时使用Runloop与App默认运行时的模型不同,用PerformSelector设置当前线程的Runloop运行模式 。NSDefaultRunLoopmode:app的默认运行模式,通常情况下,主线程在本次运行中默认运行,UITrackingRunLoopMode:跟踪用户交互事件(用于ScrollView跟踪触摸滑动,确保滑动时界面不受其他模式影响 。)那么,当我们滑动UITableView时,RunLoop的运行模式就会变成UITrackingRunLoopMode 。因此,我们设置当前线程的运行模式& # 039;s RunLoop kCFRunLoopDefaultM,方法是使用将图像加载到ImageView的方法 。这样在ode滑动[cell perform selector:@ selector(setimage:)with object:nil after delay:0.1 in modes:@[NSDefaultRunLoopmode]]时就不会执行加载图片的方法;
tableview用法 tableview如何优化,tableview的优化

文章插图
如何做优化,UITabelView才能更加顺滑
内置方法我相信大多数看过这篇文章的人都知道这些方法,但是有些人,即使用过,也不会& # 039;不要以正确的姿势使用它们 。首先,重用单元格/页眉/页脚的单个实例,即使我们需要显示多个实例 。这是优化UIScrollView(UITableView的UITableView类)最明显的方法,是苹果工程师提供的 。为了正确使用它,您应该只有单元格/页眉/页脚类,初始化它们一次,然后将它们返回给UITableView 。Apple & # 039的开发文档,这里就不需要赘述了 。但重要的是:UITableView的dataSource中实现的table view:cellforrowatdinexpath:方法需要对每个单元格调用一次,而且要快速执行 。所以您需要尽快返回并重用cell实例 。不要在这里执行数据绑定,因为屏幕上目前没有单元格 。若要执行数据绑定,可以在UITableView的委托方法table view:willdisplaycell:forrowatdinexpath:中进行 。在显示单元格之前,将调用此方法 。第二点不难理解,但有一点需要说明 。这种方法不& # 039;对于具有固定单元格高度的UITableView来说没有意义,但是如果由于某种原因需要具有动态高度的单元格,它可以很容易地使滑动更加平滑 。我们知道,UITableView是UIScrollView的一个子类,UIScrollView的作用是让用户与一个比屏幕实际尺寸更大的区域进行交互 。UIScrollView的任何实例都使用contentSize、contentOffset等属性向用户显示正确的区域 。但是什么& # 039;UITableView有什么问题?如前所述,UITableView不同时维护cell的所有实例 。相反,它只需要维护那些显示给用户的单元格 。那么,UITableView是如何知道它的contentSize的呢?它通过计算所有单元格的高度之和来计算contentSize的值 。Uitview & # 039的委托方法UITableView:heightforrowatdinexpath:将为每个单元格调用一次,因此您应该很快返回高度值 。许多人会犯错误 。它们将在初始化单元实例和绑定数据后获得它们的高度 。如果你想优化滑动性能,你不应该用这种方法计算单元格的高度,因为这是非常低效的 。iOS设备标准的60 FPS会降低到15-20 FPS,滑动会变得很慢 。如果我们不& # 039;如果没有单元格的实例,我们如何计算它的高度?这里& # 039;下面是一个示例代码,它使用class方法根据传入的宽度和显示的数据计算高度值:您可以使用上面的方法通过以下方式将高度值返回给UITableView:当您意识到这一切时,您能有多少乐趣呢?大多数人会说不 。我没有 。我不能保证这很容易 。当然,我们可以构建自己的类来手动布局和计算高度,但有时我们不会& # 039;我没有足够的时间做这件事 。你可以在Telegram & # 039s iOS应用程序代码 。从iOS 8开始,我们可以在UITableView的delegate中使用自动高度计算,而无需实现上述方法 。要实现此功能,可以使用AutoLayout并将rowHeight变量设置为UITableViewAutomaticDimension 。您可以在StackOverflow中找到更详细的信息 。虽然这些方法都可以用,但是我强烈建议不要用 。另外,我不& # 039;不建议使用复杂的数学计算来获得细胞的高度 。如果可能的话,就用加减乘除 。但是如果它& # 039;s自动布局?真的有我说的那么慢吗?你可能会感到惊讶,但它& # 039;这是事实 。如果你想让你的应用在所有设备上流畅滚动,你会发现这种方法慢得令人难以置信 。使用的子视图越多,自动版式的效率就越低 。自动布局相对低效的原因是名为& quot食火鸡& quot隐藏在底层 。如果布局中的子视图越多,需要解决的约束就越多,将单元格返回到UITableView所需的时间就越长 。
用少量的值进行基本的数学计算,和找系统解大量的线性方程组或不等式,哪个更快?现在想象一下,用户想要快速滑动,每个单元格的自动布局也进行疯狂的计算 。使用内置方法优化UITableView的正确方法是:重用单元格实例:对于特殊类型的单元格,应该只有一个实例,不能多 。不要在cellForRowAtIndexPath:方法中绑定数据,因为此时尚未显示该单元格 。您可以在UITableView的委托中使用table view:willdisplaycell:forrowatdinexpath:方法 。快速计算单元格高度 。对于工程师来说,这是例行的工作,但你会因为你在优化复杂细胞的平滑滑动方面的耐心而得到回报 。我们需要更进一步 。当然,上面提到的这几点还不足以实现真正的平滑滚动,尤其是当你需要实现一些复杂的单元格(比如大量的渐变、视图、交互元素、一些装饰元素等)的时候 。),这一点变得尤为明显 。在这种情况下,UITableView很容易变得很慢,即使完成了上述所有操作 。UITableViewCell中的视图越多,滑动时的FPS越低 。但是使用手动布局和优化高度计算后,问题就不在布局,而在渲染 。让& # 039;的重点是UIView的不透明属性 。文档中说是用来辅助绘图系统定义UIView是否透明的 。如果不透明,绘图系统可以在渲染视图时进行一些优化,以提高性能 。我们是否需要性能?用户可能会快速滑动表格,比如使用scrollsToTop功能,但他们可能没有最新的iPhone,所以单元格必须快速渲染 。比通常的看法要快 。渲染中最慢的操作之一是混合 。混音是由GPU来完成的,因为这个硬件是用来混音的(当然不仅仅是混音) 。您可能已经猜到,提高性能的方法是减少混合操作的次数 。但在此之前,我们需要找到它 。让& # 039;让我们试试 。在iOS模拟器上运行应用程序,选择& # 039;调试& # 039;在模拟器的菜单中,然后选择& # 039;颜色混合层& # 039;然后iOS模拟器会用两种颜色显示整个区域:绿色和红色 。绿色区域未混合,红色区域表示有混合操作 。如你所见,cell中至少有两个混合操作,但你可能看不出区别(这个混合操作是不必要的) 。每一种情况都要仔细研究,不同的情况需要不同的方法,避免混用 。在这里,我需要做的就是设置backgroundColor来实现不透明 。但有时会更复杂 。看这个:我们有渐变,但是没有混合 。如果你想用CAGradientLayer达到这个效果,你会失望的:在iPhone 6中,FPS会降到25-30,快速滑动变得不可能 。这确实发生了,因为我们混合了两个不同层的内容:UILabel的CATextLayer和我们的CAGradientLayer 。如果能正确使用CPU和GPU资源,就会平均负载,FPS保持在60帧 。看起来是这样的:当设备需要进行大量的混合运算时,问题就出现了:GPU满载,但CPU保持低负载,所以用处不大 。大多数工程师在2010年夏末iPhone 4发布时都面临这个问题 。苹果发布了革命性的视网膜显示屏和…一个非常普通的GPU 。然而,通常它仍然有足够的容量,但上面描述的问题越来越频繁 。你可以在目前运行iOS 7的iPhone 4上看到这种现象——所有应用都变得很慢,即使是最简单的应用 。然而,通过应用本文介绍的方法,即使在这种情况下,您的应用程序也可以达到60 FPS,尽管这有点困难 。那么,你需要做什么?其实解决方法就是:用CPU渲染!这将不会加载GPU,因此无法执行混合操作 。例如,在执行动画的CALayer上 。
我们可以在UIView的drawRect:方法中使用CoreGraphics操作进行CPU渲染,如下图:这段代码好看吗?我& # 039;我会告诉你别的 。即使这样,你也会撤销一些UIView上的所有缓存优化操作(在任何情况下都是不必要的) 。但是这种方法禁用了一些混合操作,卸载了GPU,从而使得UITableView更加流畅 。但是要记住:这提高了渲染性能,并不是因为CPU比GPU快!它允许我们通过让CPU执行某些渲染任务来卸载GPU,因为在许多情况下,CPU可能不会100%加载 。混合运算的关键点是平衡CPU和GPU的负载 。UITableView中优化绘图数据操作总结:减少iOS进行无用混合的区域:don & # 039t使用透明背景,使用iOS模拟器或仪器来确认这一点;如果可能的话,尽量不要混合使用渐变 。优化代码,平衡CPU和GPU的负载 。你需要清楚的知道渲染哪个部分需要GPU,哪个部分可以使用CPU,这样才能保持一个平衡 。为特殊的单元格类型编写特殊的代码 。获取像素 。你知道像素长什么样吗?我的意思是,屏幕上的物理像素是什么样的?我& # 039;我相信你知道,但我还是想让你看一看:不同的屏幕有不同的生产工艺,但有一点是相同的 。事实上,每个物理像素由三种颜色子像素组成:红色、绿色和蓝色 。基于这一事实,像素不是原子单位,尽管它是用于应用程序的 。还是还是没有?直到视网膜屏的iPhone 4发布,物理像素都可以用整数点坐标来描述 。有了Retina屏,在Cocoa Touch环境下,我们可以用屏点代替像素,同时屏点可以是浮点值 。在一个完美的世界中(我们试图构建的),屏幕点总是被视为物理像素的整数坐标 。但在现实生活中,可能是浮点值 。例如,线段可以从x为0.25的地方开始 。此时iOS会进行亚像素渲染 。这项技术在应用于特定类型的内容(如文本)时很有意义 。但是当我们画一条平滑的直线时,就没有必要了 。如果所有平滑的线段都使用亚像素渲染技术进行渲染,那么你会让iOS执行一些不必要的任务,从而降低FPS 。什么情况下会出现这种不必要的亚像素反走样操作?最常发生的是视图坐标通过代码计算变成浮点值,或者一些不正确的图片资源,其大小与屏幕的物理像素不对齐(例如,你在Retina显示屏上有一张大小为6061的图片,而不是6060) 。前面说过,要解决问题,首先需要找到问题出在哪里 。在iOS模拟器上运行程序并选择& quot颜色不一致的图像& quot在& quot调试菜单 。这一次,有两种突出显示的区域:洋红色区域执行子像素渲染,黄色区域是图片大小未对齐的情况 。那么如何在代码中找到对应的位置呢?我一直都是用手动布局,有些会自定义绘制,所以我一般找这些地方都没问题 。如果你用界面构建器,那么我很同情它 。通常情况下,为了解决这个问题,你只需使用ceilf、floorf和CGRectIntegral方法对坐标进行舍入 。那& # 039;就是它!通过上面的讨论,我想建议以下几点:对所有像素相关的数据进行四舍五入,包括点坐标,UIView的高度和宽度 。跟踪你的图像资源:图片必须是像素完美的,否则在视网膜屏幕上渲染时会做不必要的反走样 。定期检查您的代码,因为这可能会经常发生 。异步UI也许这看起来有点奇怪,但这是一个非常有效的方法 。如果你知道怎么做,那么你就可以让UITableView滑动得更流畅 。现在让& # 039;让我们讨论一下你应该做什么,然后讨论你是否有可能这样做 。每个中型应用程序都可能使用包含媒体内容的单元格:文本、图片、动画甚至视频 。
所有这些都可能有装饰性的元素:圆形的头部,带有& # 039;#'用户名等 。我们多次提到需要尽快返回cell,但是这里有一些麻烦:clipsToBounds很慢,图片需要从网络加载,#号需要位于字符串中,等等很多问题 。优化的目标很明确:如果你在主线程中执行这些操作,你就赢了& # 039;不能很快回到牢房 。在后台加载图片,在同样的地方处理圆角,然后将处理后的图片赋给UIImageView 。立即显示文本,但在背景中找到#号,然后使用属性字符串刷新显示 。在你的细胞里,需要具体情况具体分析,但主要思路是在后台进行大操作 。可能不仅仅是网络代码,你需要用仪器去找 。记住:你需要尽快回到牢房 。有时候,以上所有技术可能都无济于事 。例如,当GPU仍然能够& # 039;t被使用(iPhone4 iOS7),当单元格内有大量内容时,需要CALayer的支持才能实现动画(因为在drawRect中实现确实很麻烦:) 。在这种情况下,我们需要在背景中渲染其他一切 。另外,在用户快速滑动UITableView时,可以有效提高FPS 。让& # 039;让我们来看看脸书的应用程序 。为了检测这些,您可能需要向下滑动足够高,然后单击状态栏 。列表将向上滑动,因此您可以清楚地看到单元格此时没有呈现 。如果你想更准确,你可以& # 039;我不能及时得到它 。它& # 039;很简单,你可以自己试试 。此时,需要将CALayer的drawsAsynchronously属性设置为YES 。但是我们可以检查这些行为的必要性 。在iOS模拟器上运行程序,然后选择& quot屏幕外渲染的颜色在& quot调试菜单 。现在,背景中渲染的所有区域都以黄色突出显示 。如果你为某些图层打开了这种模式,但它没有被高亮显示,那么它就不够慢 。要找到CALyaer层中的瓶颈并进一步减少它,可以使用Instruments中的时间分析器 。下面是异步UI的实现列表:找到阻止你的单元格快速返回的瓶颈 。将操作移到后台线程,刷新主线程中显示的内容 。最后一个办法是将你的CALayer设置为异步显示模式(即使它& # 039;只是简单的文字或图片)——这将有助于你提高FPS 。结论我试着解释了一下iOS绘图系统的主要思想(OpenGL因为案例少所以没用) 。当然有些看起来很模糊,但其实这些只是一些方向 。您应该从这些方面检查您的代码,找出所有影响滚动性能的问题 。具体情况具体分析,但原则不变 。完美平滑滚动的关键是一个非常特殊的代码,它可以让你尽最大努力让你的应用程序更流畅 。

    推荐阅读