in iOS apps, UITableView should be one of the most used views. It's important to see the IPod, Clock, Calendar, Memo, Mail, weather, photos, phone, SMS, Safari, App Store, ITunes, Game Center almost all of your own apps.
however, when using third-party applications, they often encounter performance problems, and generally appear to compare cards when scrolling, especially when the table cell contains pictures.
in fact, as long as the targeted optimization, this problem will not be. be interested to seeLazytableimagesThis official example program, although also to download pictures from the Internet and display, but the slightest scroll when the card.
Let's talk about my understanding of UITableView. However, because I am also a beginner, may be wrong or omitted some, so for reference only.
first, the principle of uitableview. be interested to see"About Table views in ios-based Applications".
UITableView is a subclass of Uiscrollview, so it can automatically respond to scrolling events (typically scrolling up and down).
it contains 0 to more UITableViewCell objects and each table cell displays its own content. When the new cell needs to be displayed, it calls the Tableview:cellforrowatindexpath: method to get or create a cell, and when it is not, it is freed. This shows that at the same time, only one screen of the cell object is needed, and there is no need to create a cell for each row.
In addition, UITableView can be divided into multiple sections, each of which can have its own head, foot, and cells. When locating a cell, you need 2 fields: in which section, and in the first line of the sections. This is expressed in Nsindexpath in the iOS SDK, and Uikit adds indexpathforrow:insection to it: This method of creation.
other things such as editing are not mentioned, because it is not related to this article.
after the introduction of the principle, the next step is to optimize it.
-
use opaque view 。
Front said, UITableView requires only one screen of UITableViewCell objects. So when the cell is not visible, you can cache it and continue to use it when you need it.
static nsstring *cellidentifier = @ "xxx";
uitableviewcell *cell = [tableview dequeuereusablecellwithidentifier:cellidentifier];
if (cell == nil) {
cell = [[[uitableviewcell alloc] initwithstyle:uitableviewcellstyledefault reuseidentifier:cellidentifier] autorelease];
}
It is worth mentioning that when the cell is reused, the content drawn inside it is not automatically cleared, so you may need to call the Setneedsdisplayinrect: or Setneedsdisplay method.
errata: Just test this on the simulator , there is no such bug when debugging a real machine.
Reduce the number of views.
uitableviewcell contains Textlabel, Detailtextlabel, and ImageView view, and you can customize some of the views in its contentview. However, view is a large object, and creating it consumes more resources and also affects rendering performance.
if your table The cell contains pictures, and the number is large, and using the default UITableViewCell can have a significant impact on performance. Oddly, using a custom view, rather than a predefined view, is significantly faster.
of course, The best solution is to inherit UITableViewCell and draw in its drawrect:
- (void) DrawRect: (CGRect) rect {
if (image) {
[image drawAtPoint:imagePoint];
self.image = nil;
} else {
[placeholder drawatpoint:imagepoint];
}
[Text drawinrect:textrect withfont:font linebreakmode: Uilinebreakmodetailtruncation];
}
However, you will find that when you select a row, the cell becomes blue and the contents are blocked. The simplest way is to set the cell's Selectionstyle property to Uitableviewcellselectionstylenone so it won't be highlighted.
-
don't do extra drawing work 。
For example, in the above example, You can use Cgrectintersectsrect, cgrectintersection, or cgrectcontainsrect to determine whether you need to draw an image and text, and then call the drawing method.
Pre-rendered images.
You will find that even if the above points are achieved, there will still be a brief pause when the new image appears. The solution is to draw it once in the bitmap context, export it to a UIImage object, and then draw it to the screen, with detailed instructions for accelerating the image display of the iOS device using pre-rendering.
do not block the main thread.
When you do, your table view should be smooth enough to scroll, but you can still make users feel uncomfortable. The common phenomenon is that when updating data, the entire interface is stuck and does not respond to user requests at all.
This behavior occurs because the main thread executes a long-time function or method that cannot draw the screen and respond to user requests until it finishes executing. The most common of these is the network request, which usually takes a few seconds, and you should not let the user wait that long.
The workaround is to use multi-threading to let the child threads execute the functions or methods. There is also a knowledge that, when the number of download threads exceeds 2 o'clock, it can significantly affect the performance of the main thread. So when using ASIHTTPRequest, you can use a nsoperationqueue to maintain the download request and set its maxconcurrentoperationcount to 2. Nsurlrequest can be implemented with GCD, or using Nsurlconnection's Setdelegatequeue: method.
Of course, you can also increase the number of download threads to speed up download times when you don't need to respond to user requests:
-(void) scrollviewdidenddragging: (Uiscrollview *) ScrollView willdecelerate: (BOOL) decelerate {
if (!decelerate) {
Queue.maxconcurrentoperationcount = 5;
}
}
-(void) scrollviewdidenddecelerating: (Uiscrollview *) ScrollView {
Queue.maxconcurrentoperationcount = 5;
}
-(void) scrollviewwillbegindragging: (Uiscrollview *) ScrollView {
Queue.maxconcurrentoperationcount = 2;
}
In addition, automatic loading of updated data is also friendly to users, which reduces the time users wait to download. For example, if you load 50 messages at a time, you can load more information when you scroll to the bottom 10th:
-(void) TableView: (UITableView *) TableView Willdisplaycell: (UITableViewCell *) cell Forrowatindexpath: (Nsindexpath *) Indexpath {
if (Count-indexpath.row < &&!updating) {
updating = YES;
[Self UPDATE];
}
}
After the Update method obtains the result, set updating to No
It is also important to note that when the picture is downloaded, if the cell is visible, you also need to update the image:
can also not traverse, directly and the tail and the comparison, see whether in the middle can.
Finally, the insertrowsatindexpaths:withrowanimation: method, inserting a new line needs to be executed on the main thread, and inserting many rows at a time (for example, 50 rows), which will block the main thread for long. and replaced by the Reloaddata method, the instant processing is done.
This article is from the "I am the way of it Growth" blog, please be sure to keep this source http://jeason.blog.51cto.com/9704473/1728824
IOS improves TableView performance optimization