在Swift加载JSON中加速TableView

时间:2015-09-16 07:55:34

标签: ios json swift uitableview

我目前正在开发一个JSON TableView,其中包含我的数据库中的信息(一些带有图像及其名称的产品)。一切都很好但是当我向下滚动(或向上)时速度很慢。我已就此主题进行了大量研究,但我已尝试过他们的代码,但我仍然不知道如何将图像存储在缓存中以加速TableView。

这是我的代码:

x = 100;
j = batch('size(x)')

当从我的JSON文件向下滚动“产品”时,如何加快我的TableView?

提前致谢,

问候。

3 个答案:

答案 0 :(得分:3)

为每个新的/重用的单元格渲染调用

cellForRowAtIndexPath:。您不应该在此方法中进行服务器调用。这就是你应该这样做的方式:

  1. 在您的数据对象" productos"之后填充后,调用一个新方法fetchImages,它可以在后台触发NSOperations来获取图像。
  2. 在提取图像时,您可以在每个单元格图像视图上显示加载叠加。
  3. 图像响应返回后,删除加载覆盖并刷新单元格。
  4. 在用户在桌面视图中向上和向下滚动时,缓存文件系统中的图像以避免再次重新获取它们。
  5. 遵循这一点,您应该看到应用程序滚动行为的所需改进。

    编辑:关于OP请求:

    第1步:从服务器加载模型数据后,您希望在fetchImages方法下调用。如果您在本地加载数据,请在fetchImages中调用loadView

    - (void)fetchImages {
        NSMutableArray *anImageURLsList = [NSMutableArray new]; // Assuming this contains your image URL list
    
        if ([anImageURLsList count] > 0) {
            __weak MyController *aBlockSelf = self;
    
            [[MyImageFetchController sharedImageFetchController] addURLs:anImageURLsList withDescription:[self description] andCompletionBlock:^(NSMutableArray *iFailedURLs) {
                dispatch_async(dispatch_get_main_queue(), ^{[UIApplication sharedApplication].networkActivityIndicatorVisible = NO; });
    
                if (aBlockSelf) {
                    [[MyImageFetchController sharedImageFetchController].objectTokens seValue:[NSString stringWithFormat:@"%d", NO] forKey:[aBlockSelf description]];
                    [aBlockSelf performSelectorOnMainThread:@selector(refresh) withObject:nil waitUntilDone:YES];
                }
            }];
    
            [[MyImageFetchController sharedImageFetchController].objectTokens setValue:[NSString stringWithFormat:@"%d", YES] forKey:[self description]];
            [MyImageFetchController sharedImageFetchController].delegate = self;
            [[MyImageFetchController sharedImageFetchController] startOperations];
    
        dispatch_async(dispatch_get_main_queue(), ^{[UIApplication sharedApplication].networkActivityIndicatorVisible = YES; });
        }
    }
    
    
    - (void)refresh {
        [self.tableView reloadData];
    }
    

    第2步:现在让我们编写NSOperation子类来通过操作队列获取图像。下面的代码仅涵盖了有关此处讨论的重要方面。在这里,我已经给出了一个代表回调图像缓存实现。

    - (void)addURLs:(NSMutableArray *)iURLs withDescription:(NSString *)iObjectDescription andCompletionBlock:(ImageFetchCompletionBlock)iImageFetchCompletionBlock {
        self.urls = iURLs;
        [self.objectTokens removeAllObjects];
        self.imageFetchCompletionBlock = iImageFetchCompletionBlock;
        self.objectDescription = iObjectDescription;
    
        if (self.failedURLs) {
            [self.failedURLs removeAllObjects];
        }
    }
    
    
    - (void)urlFailed:(NSString *)iFailedURL {
        @synchronized(self) {
            if (iFailedURL) {
                [self.failedURLs addObject:iFailedURL];
            }
        }
    }
    
    
    - (void)startOperations {
        MyImageFetchOperation *anImageFetchOperation = nil;
        NSMutableArray *anOperationList = [[NSMutableArray alloc] initWithCapacity:self.urls.count];
        self.queue = [NSOperationQueue new];
    
        for (NSString *aURL in [self.urls copy]) {
            anImageFetchOperation = [[MyImageFetchOperation alloc] initWithImageURL:aURL delegate:self];
            [anOperationList addObject:anImageFetchOperation];
        }
    
        [self.queue setMaxConcurrentOperationCount:3];
        [self.queue addOperations:anOperationList waitUntilFinished:NO];
    }
    
    
    - (void)operationCompletedForURL:(NSString *)iImageURL {
        @synchronized(self) {
            [self.urls removeObject:iImageURL];
    
            if ([self.urls count] == 0) {
                if ([[self.objectTokens valueForKey:self.objectDescription] boolValue]) {
                    self.imageFetchCompletionBlock([self.failedURLs mutableCopy]);
                } else {
                    dispatch_async(dispatch_get_main_queue(), ^{[UIApplication sharedApplication].networkActivityIndicatorVisible = NO; });
                }
    
                if (self.failedURLs && [self.failedURLs count] > 0) {
                    [self.failedURLs removeAllObjects];
                }
    
                self.queue = nil;
            }
        }
    }
    
    
    - (NSString *)cacheDirectoryForImages {
        NSString *anImageCacheDirectory = kImageCacheDirectoryKey; // Your image cache directory 
    
        if (self.delegate && [self.delegate respondsToSelector:@selector(cacheDirectoryForImages)]) {
            anImageCacheDirectory = [self.delegate cacheDirectoryForImages];
        }
    
        return anImageCacheDirectory;
    }
    

    第3步:现在,我们来写cellForRowAtIndexPath。在这里,我使用的是一个自定义单元格,它实现了一个imageView,并期望一个自定义加载叠加层。您可以在此处加载加载叠加层。

    - (UITableViewCell *)tableView:(UITableView *)iTableView cellForRowAtIndexPath:(NSIndexPath *)iIndexPath {
        NSString *cellType = @"defaultCell";
        MyCustomTableViewCell *cell = (MyCustomTableViewCell *)[iTableView dequeueReusableCellWithIdentifier:cellType];
    
        if (!cell) {
            cell = [[MyCustomTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:aCellType];
        }
    
        cell.textLabel.text = @“Dummy”; // Set your cell data
    
        NSString *anImageURL = self.productos[iIndexPath.row][@“image"];
    
        [cell.loadingOverlay removeView];
        cell.loadingOverlay = nil;
    
        // If image is present in Cache
        if (anImageURL && [anImageURL existsInCache]) {
            cell.imageView.image = [UIImage imageNamed:<Image from cache>];
        } else if ([[[MyImageFetchController sharedImageFetchController].objectTokens valueForKey:[self description]] boolValue]) {
            cell.imageView.image = [UIImage imageNamed:defaultImage];
            cell.loadingOverlay = [MyLoadingOverlay loadingOverlayInView:aCell.imageView];
        } else {
            cell.imageView.image = [UIImage imageNamed:defaultImage];
        }
    
        return cell;
    }
    

答案 1 :(得分:0)

对于延迟加载,您应该使用SDWebImage Library。它为您提供捕捉图像和还提供了在为每个单元格加载图像时添加加载程序的功能。
请点击此链接在您的应用中集成SDWebImage。
https://github.com/rs/SDWebImage

答案 2 :(得分:0)

关于图像加载性能(将其移至后台线程,将图像存储到内存缓存等)。以下是重复的问题:

display downloaded images in tableview

Async image loading from url inside a UITableView cell - image changes to wrong image while scrolling