我正在使用AFNetworking将JSON解析为我的应用程序(使用Rails作为我的后端)。现在我的应用程序非常慢,所以我想找到一种方法让它更顺畅。当我第一次加载应用程序时,它需要几秒钟才能填充(它显示导航项目和白页,然后几秒钟后我的“帖子”出现)。
集合视图控制器
- (void)viewDidLoad
{
[super viewDidLoad];
self.upcomingReleases = [[NSMutableArray alloc] init];
[self makeReleasesRequests];
[self.collectionView registerClass:[ReleaseCell class] forCellWithReuseIdentifier:@"ReleaseCell"];
}
-(void)makeReleasesRequests
{
NSURL *url = [NSURL URLWithString:@"http://www.soleresource.com/upcoming.json"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
operation.responseSerializer = [AFJSONResponseSerializer serializer];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"@");
self.upcomingReleases = [responseObject objectForKey:@"upcoming_releases"];
[self.collectionView reloadData];
} failure:nil];
[operation start];
}
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
return 1;
}
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return [self.upcomingReleases count];
}
#pragma mark - Show upcoming release shoe
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
static NSString *identifier = @"Cell";
ReleaseCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
NSDictionary *upcomingReleaseDictionary = [self.upcomingReleases objectAtIndex:indexPath.row];
NSString *thumbURL = nil;
cell.release_name.text = [NSString stringWithFormat:@"%@ — $%@",[upcomingReleaseDictionary objectForKey:@"release_name"], [upcomingReleaseDictionary objectForKey:@"release_price"]];
if ([upcomingReleaseDictionary[@"images"] isKindOfClass:[NSArray class]] && [upcomingReleaseDictionary[@"images"] count]) {
thumbURL = upcomingReleaseDictionary[@"images"][0][@"image_file"][@"image_file"][@"thumb"][@"url"];
if (thumbURL)
{
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:thumbURL]];
UIImage *image = [UIImage imageWithData:imageData];
cell.thumb.image = image;
}
}
else {
cell.thumb.image = [UIImage imageNamed:@"air-jordan-5-fear.png"];
}
return cell;
}
我的每个帖子都有文字字符串和图片。有没有办法加载文本,以便它立即出现,然后加载我的图像?或者是否有另一种方法来加快我的应用程序加载速度(可能首先加载某些帖子然后加载其余帖子 - 用户在向下滚动之前无法看到的那些)。
感谢。
答案 0 :(得分:0)
你的问题是:
if (thumbURL)
{
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:thumbURL]];
UIImage *image = [UIImage imageWithData:imageData];
cell.thumb.image = image;
}
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:thumbURL]];
UIImage *image = [UIImage imageWithData:imageData];
您永远不应该在cellForItemAtIndexPath:
中获取数据。你应该只显示你已经拥有的东西。您的代码使得在下载缩略图之前不会返回任何单元格。您可以使用仪器中的 Time Profiler 来测量它。
我假设thumb
是UIImageView。试试这个:
if (thumb) {
[thumb setImageWithURL:[NSURL URLWithString:@"http://i.imgur.com/r4uwx.jpg"]];
}
此方法也包含在AFNetworking中,将下载图像,并在完成下载后在单元格中更新。 Documentation and other similar methods are here
答案 1 :(得分:0)
当你从服务器来时,你应该懒惰和异步地加载你的图像(不要阻止主线程)。 (AFNetworking已经在UIImageView上有缓存类别方法。(查看this了解更多信息)
if (thumbURL)
{
[cell.thumb setImageWithURL:[NSURL URLWithString:thumbURL] placeholderImage:[UIImage imageNamed:@"air-jordan-5-fear.png"]];
}
编辑 -
确保将 UIKit + AFNetworking 文件夹提取到项目中,并将#import "UIKit+AFNetworking.h"
提取到.m文件中。可以找到下载完整AFNetworking的链接here以及特定于此问题的文档here。