Iphone 如何使滚动UITableView更平滑?
我有一个tableview,里面有大约20个单元格和从网上下载的图像 现在滚动时会有起伏,需要使其更平滑 我的方法是:Iphone 如何使滚动UITableView更平滑?,iphone,objective-c,performance,cocoa-touch,uitableview,Iphone,Objective C,Performance,Cocoa Touch,Uitableview,我有一个tableview,里面有大约20个单元格和从网上下载的图像 现在滚动时会有起伏,需要使其更平滑 我的方法是: - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; CustomCell *cell = (CustomCell*)[
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
CustomCell *cell = (CustomCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil];
for (id currentObject in topLevelObjects){
if ([currentObject isKindOfClass:[UITableViewCell class]]){
cell = (CustomCell *) currentObject;
break;
}
}
}
NSDictionary *article = [entriesArray objectAtIndex:[indexPath row]];
NSString *title = [article objectForKey:@"title"];
NSString *date = [article objectForKey:@"publishedDate"];
NSString *dateEdited = [date substringToIndex:16];
cell.nameLabel.text = title;
cell.dateLabel.text = dateEdited;
NSURL *myURL=[NSURL URLWithString:[self.picturesArray objectAtIndex:indexPath.row]];
NSData *myData1 = [[NSData alloc] initWithContentsOfURL:myURL];
UIImage *myImage = [[UIImage alloc] initWithData:myData1];
cell.imageView.image = myImage;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
cell.textLabel.numberOfLines = 2;
return cell;
}
有什么建议吗?有几个问题。首先,你有一些内存泄漏。myData1和myImage已创建但未发布 然而,我的猜测是,巨大的性能冲击与您创建UIImage有关。将其移出此单元格请求方法。也许可以创建一个可以利用的图像缓存。例如,将它们作为在initialize方法中创建的静态UIImage对象
我认为这将解决大部分性能问题。最后一个调整是从该方法中删除for循环。也许可以创建一个NSDictionary,以便直接查找对象。有几个问题。首先,你有一些内存泄漏。myData1和myImage已创建但未发布 然而,我的猜测是,巨大的性能冲击与您创建UIImage有关。将其移出此单元格请求方法。也许可以创建一个可以利用的图像缓存。例如,将它们作为在initialize方法中创建的静态UIImage对象
我认为这将解决大部分性能问题。最后一个调整是从该方法中删除for循环。也许可以创建一个NSDictionary,以便直接查找对象。您不应该在主事件循环中下载图像文件
尝试使用一些后台下载程序,如。您不应该下载主事件循环中的图像文件
尝试使用一些后台下载程序,如。您似乎没有在后台线程上运行网络请求,这正是您需要执行的操作。不仅从性能的角度,而且从稳定性的角度来看。如果向其发出网络请求的服务器关闭,会发生什么情况?我不确定initWithContentsOfURL:如何处理失败,但您的代码似乎没有检查该方法的失败,因此您的程序似乎会因网络问题而崩溃
在后台线程上实现fetch不会导致主线程阻塞,从而使UITableView能够更无缝地滚动,但是,这样做的折衷办法是,在等待后台线程完成网络请求时,表视图图像可能会空白一段时间。您似乎没有在后台线程上运行网络请求,这是您需要执行的操作。不仅从性能的角度,而且从稳定性的角度来看。如果向其发出网络请求的服务器关闭,会发生什么情况?我不确定initWithContentsOfURL:如何处理失败,但您的代码似乎没有检查该方法的失败,因此您的程序似乎会因网络问题而崩溃
在后台线程上实现fetch不会导致主线程阻塞,从而使UITableView能够更无缝地滚动,但是,这样做的折衷办法是,在等待后台线程完成网络请求时,表视图图像可能会空白一段时间。这就是加载自定义单元格的方式
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
CustomCell *cell = (CustomCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIndetifier];
}
NSDictionary *article = [entriesArray objectAtIndex:[indexPath row]];
NSString *title = [article objectForKey:@"title"];
NSString *date = [article objectForKey:@"publishedDate"];
NSString *dateEdited = [date substringToIndex:16];
cell.nameLabel.text = title;
cell.dateLabel.text = dateEdited;
NSURL *myURL=[NSURL URLWithString:[self.picturesArray objectAtIndex:indexPath.row]];
NSData *myData1 = [[NSData alloc] initWithContentsOfURL:myURL] autorelease];
UIImage *myImage = [[UIImage alloc] initWithData:myData1] autorelease];
cell.imageView.image = myImage;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
cell.textLabel.numberOfLines = 2;
return [cell autorelease];
}
这就是加载自定义单元格的方式
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
CustomCell *cell = (CustomCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIndetifier];
}
NSDictionary *article = [entriesArray objectAtIndex:[indexPath row]];
NSString *title = [article objectForKey:@"title"];
NSString *date = [article objectForKey:@"publishedDate"];
NSString *dateEdited = [date substringToIndex:16];
cell.nameLabel.text = title;
cell.dateLabel.text = dateEdited;
NSURL *myURL=[NSURL URLWithString:[self.picturesArray objectAtIndex:indexPath.row]];
NSData *myData1 = [[NSData alloc] initWithContentsOfURL:myURL] autorelease];
UIImage *myImage = [[UIImage alloc] initWithData:myData1] autorelease];
cell.imageView.image = myImage;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
cell.textLabel.numberOfLines = 2;
return [cell autorelease];
}
我要检查的第一个地方(也是一个很容易忽略的地方)是确保在CustomCell.xib文件中正确设置了单元格的重用标识符(在您的情况下设置为“cell”) 例如: 创建您的单元格。假设您有一个名为CustomCell.xib的nib,您应该在视图控制器中创建一个IBOutlet: @属性(非原子,保留)IBUITableViewCell*customCell 然后在CustomCell nib中,将文件的所有者设置为视图控制器,并将单元格连接到文件所有者的自定义单元格出口 要创建单元格,请使用以下代码:
- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if(cell == nil)
{
[[NSBundle mainBundle] loadNibNamed: @"CustomCell" owner: self options: nil];
cell = self.customCell;
self.customCell = nil;
}
// Customise your cell here
return cell;
}
我要检查的第一个地方(也是一个很容易忽略的地方)是确保在CustomCell.xib文件中正确设置了单元格的重用标识符(在您的情况下设置为“cell”) 例如: 创建您的单元格。假设您有一个名为CustomCell.xib的nib,您应该在视图控制器中创建一个IBOutlet: @属性(非原子,保留)IBUITableViewCell*customCell 然后在CustomCell nib中,将文件的所有者设置为视图控制器,并将单元格连接到文件所有者的自定义单元格出口 要创建单元格,请使用以下代码:
- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if(cell == nil)
{
[[NSBundle mainBundle] loadNibNamed: @"CustomCell" owner: self options: nil];
cell = self.customCell;
self.customCell = nil;
}
// Customise your cell here
return cell;
}
您需要懒洋洋地加载图像。这意味着将它们加载到另一个线程中。苹果有。你需要懒洋洋地加载你的图像。这意味着将它们加载到另一个线程中。苹果有。谢谢,我不需要这个循环,我在这个网站上找到了它,这是我定制手机加载的唯一方式。没有它我怎么办?当我这样做时,它会崩溃并出现错误:
***由于未捕获的异常而终止应用程序“nsInternalInConsistencException”,原因:“UITableView数据源必须从tableView返回一个单元格:cellForRowAtIndexPath:”
使用其init方法创建自定义单元格。因此,基本上,您可以调用dequeuereusablemethod。如果返回nil,则在那里创建单元格,然后单击。调用DequeueReusables是为了避免创建cell类,除非必须这样做<代码>-(id)initWithStyle:(UITableViewCellStyle)样式重用标识符:(NSString*)重用标识符。cellForRowAtIndexPath必须返回一个单元格。当您调用出列时,这将为您提供一个现有的单元格,您将使用数据填充该单元格并返回。或者,它会给你零。如果它给出nil,那么在cellForRowAtIndexPath中您必须创建一个新的单元格-可能使用initWithStyle-然后您返回它。谢谢,我