Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/41.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 如何使滚动UITableView更平滑?_Iphone_Objective C_Performance_Cocoa Touch_Uitableview - Fatal编程技术网

Iphone 如何使滚动UITableView更平滑?

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*)[

我有一个tableview,里面有大约20个单元格和从网上下载的图像

现在滚动时会有起伏,需要使其更平滑

我的方法是:

- (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-然后您返回它。谢谢,我