Uitableview滚动滞后与Lazyloading(苹果源代码)

时间:2014-07-05 11:20:01

标签: ios objective-c uitableview

我试图弄清楚为什么我的程序在模拟器上运行良好但在手机上运行不正确。

当我滚动我的桌子时,它变得迟钝。

我尝试了一切,甚至删除了我的图片加载但仍然发生滚动延迟。

我正在使用apple lazy loading源代码:

这是我的代码:

#define kCustomRowCount     7


@interface SubCategoryViewController () <UIScrollViewDelegate>

@property (nonatomic, strong) NSMutableDictionary *imageDownloadsInProgress;
@property (nonatomic, strong) NSMutableDictionary *imageRestitleDownloadsInProgress;
@property (nonatomic, assign) int intindex;
@end


@implementation SubCategoryViewController

#pragma mark


- (void)viewDidLoad
{

    [super viewDidLoad];
    self.title = self.catname;
    self.imageDownloadsInProgress = [NSMutableDictionary dictionary];
    self.imageRestitleDownloadsInProgress = [NSMutableDictionary dictionary];
}


- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];

    NSArray *allDownloads = [self.imageDownloadsInProgress allValues];
    [allDownloads makeObjectsPerformSelector:@selector(cancelDownload)];

    NSArray *allDownloads2 = [self.imageRestitleDownloadsInProgress allValues];
    [allDownloads2 makeObjectsPerformSelector:@selector(cancelDownload)];

    [self.imageDownloadsInProgress removeAllObjects];
    [self.imageRestitleDownloadsInProgress removeAllObjects];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    NSUInteger count = [self.entries count];

    // if there's no data yet, return enough rows to fill the screen
    if (count == 0)
    {
        return kCustomRowCount;
    }
    return count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{

    static NSString *PlaceholderCellIdentifier = @"PlaceholderCell2";


    NSUInteger nodeCount = [self.entries count];

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:PlaceholderCellIdentifier];
    cell.contentView.translatesAutoresizingMaskIntoConstraints = NO;
    UILabel *newsbody = (UILabel *)[cell.contentView viewWithTag:6];
    UIImageView *uimg = (UIImageView *)[cell.contentView viewWithTag:20];
    UIImageView *uimgresttile = (UIImageView *)[cell.contentView viewWithTag:23];


    if (nodeCount == 0 && indexPath.row == 0)
    {


        if (cell == nil) {

            uimg.hidden = true;
            uimgresttile.hidden = true;
            newsbody.hidden = true;


        }
        else
        {
            uimg.hidden = true;
            uimgresttile.hidden = true;
            newsbody.hidden = true;


        }

        return cell;
    }
    if (nodeCount == 0 && indexPath.row > 0)
    {
        cell.hidden = true;
        return cell;
    }



    if (nodeCount > 0)
    {

        uimg.hidden = false;
        uimgresttile.hidden = false;
        newsbody.hidden = true;

        NewsFetchAppRecord *appRecord = [self.entries objectAtIndex:indexPath.row];
        [newsbody setText:appRecord.Body];

        if (!appRecord.appIcon)
        {
             if (self.tableView.dragging == NO && self.tableView.decelerating == NO)

             {
                 [self startIconDownload:appRecord forIndexPath:indexPath];

             }


             uimg.image = [UIImage imageNamed:@"Placeholder.png"];

         }
         else
         {
             uimg.image = appRecord.appIcon;

         }
         if (!appRecord.appIconrestitle)
         {
             if (self.tableView.dragging == NO && self.tableView.decelerating == NO)
             {
                  [self startRestitleIconDownload:appRecord forIndexPath:indexPath];

             }


              uimgresttile.image = [UIImage imageNamed:@"Placeholder.png"];
         }
         else
         {

              uimgresttile.image = appRecord.appIconrestitle;
         }
    }
     if ((unsigned long)indexPath.row == [self.entries count] - 1){
         dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0),
                        ^{
                            NewsFetchParseOperation *p = [[NewsFetchParseOperation alloc]init];
                            NewsFetchAppRecord *appRecord = [self.entries objectAtIndex:indexPath.row];


                            p.cat = appRecord.Category;
                            self.intindex = self.intindex + 1;
                            p.index = [NSString stringWithFormat:@"%d", (int)self.intindex];
                            p.lastid = appRecord.ids;
                            [p main];
                            dispatch_async(dispatch_get_main_queue(), ^(void)
                                           {

                                                SubCategoryViewController *svc =[self.storyboard instantiateViewControllerWithIdentifier:@"SubCategory"];
                                               NSArray *temp =[self.entries arrayByAddingObjectsFromArray:p.appRecordList];
                                                self.entries = temp;
                                               [self.tableView reloadData];

                                           });
                        });

     }
    return cell;

}

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{


    static NSString *PlaceholderCellIdentifier = @"PlaceholderCell2";


    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:PlaceholderCellIdentifier];

    [cell setNeedsUpdateConstraints];
    [cell updateConstraintsIfNeeded];

    cell.bounds = CGRectMake(0.0f, 0.0f, CGRectGetWidth(tableView.bounds), CGRectGetHeight(cell.bounds));

    [cell setNeedsLayout];
    [cell layoutIfNeeded];

    CGFloat height = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;

    height += 1;

    return height;

}

- (void)startIconDownload:(NewsFetchAppRecord *)appRecord forIndexPath:(NSIndexPath *)indexPath
{
    NewsFetchIconDownloader *iconDownloader = [self.imageDownloadsInProgress objectForKey:indexPath];

    if (iconDownloader == nil)
   {
        iconDownloader = [[NewsFetchIconDownloader alloc] init];
        iconDownloader.newsfetchappRecord = appRecord;
        [iconDownloader setCompletionHandler:^{

            UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
            UIImageView *uimg = (UIImageView *)[cell.contentView viewWithTag:20];
            uimg.image = appRecord.appIcon;

            [self.imageDownloadsInProgress removeObjectForKey:indexPath];

        }];
        [self.imageDownloadsInProgress setObject:iconDownloader forKey:indexPath];
       [iconDownloader startDownload];
    }

}
- (void)startRestitleIconDownload:(NewsFetchAppRecord *)appRecord forIndexPath:(NSIndexPath *)indexPath
{

    NewsFetchRestitleIconDownloader *ResttitleiconDownloader = [self.imageRestitleDownloadsInProgress objectForKey:indexPath];

    if (ResttitleiconDownloader == nil)
    {
        ResttitleiconDownloader = [[NewsFetchRestitleIconDownloader alloc] init];
        ResttitleiconDownloader.newsfetchappRecord = appRecord;
        [ResttitleiconDownloader setCompletionHandler:^{

            UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
            UIImageView *uimgresttile = (UIImageView *)[cell.contentView viewWithTag:23];

            uimgresttile.image = appRecord.appIconrestitle;


            [self.imageRestitleDownloadsInProgress removeObjectForKey:indexPath];

        }];
        [self.imageRestitleDownloadsInProgress setObject:ResttitleiconDownloader forKey:indexPath];
        [ResttitleiconDownloader startDownload];
    }
}

- (void)loadImagesForOnscreenRows
{
    if ([self.entries count] > 0)
    {
        NSArray *visiblePaths = [self.tableView indexPathsForVisibleRows];
        for (NSIndexPath *indexPath in visiblePaths)
        {
            NewsFetchAppRecord *appRecord = [self.entries objectAtIndex:indexPath.row];

            if (!appRecord.appIcon)
            {
                [self startIconDownload:appRecord forIndexPath:indexPath];
            }

        }
    }
}



- (void)loadRestitleImagesForOnscreenRows
{
    if ([self.entries count] > 0)
   {
        NSArray *visiblePaths = [self.tableView indexPathsForVisibleRows];
        for (NSIndexPath *indexPath in visiblePaths)
        {
           NewsFetchAppRecord *appRecord = [self.entries objectAtIndex:indexPath.row];

           if (!appRecord.appIconrestitle)
            {
                [self startRestitleIconDownload:appRecord forIndexPath:indexPath];
            }
       }
    }
}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
    if (!decelerate)
    {
        [self loadImagesForOnscreenRows];
      [self loadRestitleImagesForOnscreenRows];
     }
  }

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    [self loadImagesForOnscreenRows];
   [self loadRestitleImagesForOnscreenRows];
}

@end

编辑:

在iphone中如果我滚动表格,它会冻结并跳转大部分时间。即使

图片正确加载。这个问题永远不会发生在模拟器中,只能发生在真实设备中。

我在这里阅读的大部分文章基于“uitableview”滞后。大多数人建议使用asnyc

下载图像的方法。即时通讯使用苹果懒惰加载样本方法所以我想图像

除了主线程之外,

被下载。

我认为我到目前为止一直在逐段评论大部分代码并且仍然滞后

happend。

我甚至从故事板中移除了大部分内容,但仍然发生了滞后现象。

1 个答案:

答案 0 :(得分:1)

您应该删除所有图像下载方法。同时删除scrollViewDidEndDraggingscrollViewDidEndDecelerating。我不知道为什么你的heightForRowAtIndexPath如此复杂。每一行都有不同的大小吗?如果没有使用一个简单的案例陈述,你会得到几个案例。每行的不同高度可能会拖累资源。

现在为cellForRowAtIndexPath

  1. 如果你正在做的隐藏的不隐藏的东西是为了表现你应该删除所有这些。
  2. AFNetworking添加到您的项目中。如果你正在使用cocaopods(你应该)可以在你的Podfile中在线添加它。使用iOS开发使用库时,这是一个很好的做法,AFNetworking是获取网络图像等内容的最佳选择。
  3. #import "UIImageView+AFNetworking.h"
  4. 现在您所有的图像工作都是通过一行代码完成的(AFNetworking将为您处理所有缓存和性能相关问题以及异步内容):

    [uimg setImageWithURL:"http://blahbahblah.com" placeholderImage:someUIIMage]