我目前正在开发一个JSON TableView,其中包含我的数据库中的信息(一些带有图像及其名称的产品)。一切都很好但是当我向下滚动(或向上)时速度很慢。我已就此主题进行了大量研究,但我已尝试过他们的代码,但我仍然不知道如何将图像存储在缓存中以加速TableView。
这是我的代码:
x = 100;
j = batch('size(x)')
当从我的JSON文件向下滚动“产品”时,如何加快我的TableView?
提前致谢,
问候。
答案 0 :(得分:3)
cellForRowAtIndexPath:
。您不应该在此方法中进行服务器调用。这就是你应该这样做的方式:
fetchImages
,它可以在后台触发NSOperations来获取图像。遵循这一点,您应该看到应用程序滚动行为的所需改进。
编辑:关于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)
关于图像加载性能(将其移至后台线程,将图像存储到内存缓存等)。以下是重复的问题: