1

我正在使用 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;
}

我的每个帖子都有一个文本字符串和一个图像。有没有办法加载文本以便它立即出现然后加载我的图像?或者是否有另一种方法可以加快我的应用程序加载速度(可能先加载某些帖子,然后再加载其余帖子 - 用户在向下滚动之前无法看到的帖子)。

谢谢。

4

2 回答 2

0

当来自服务器时,您应该延迟和异步加载图像(不要阻塞主线程)。(AFNetworking 已经在 UIImageView 上有缓存类别方法。(查看更多

    if (thumbURL)
    {
        [cell.thumb setImageWithURL:[NSURL URLWithString:thumbURL] placeholderImage:[UIImage imageNamed:@"air-jordan-5-fear.png"]];
    }

编辑-

确保将UIKit+AFNetworking文件夹拉到您的项目和#import "UIKit+AFNetworking.h".m 文件中。可以在此处找到下载完整 AFNetworking 的链接,并在此处找到针对此问题的文档。

于 2013-10-29T19:59:23.643 回答
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:. 你应该只展示你已经拥有的东西。您的代码使其在下载缩略图之前不会返回任何单元格。您可以使用 Instruments 中的Time Profiler进行测量。

我假设thumb是一个 UIImageView。尝试这个:

if (thumb) {
    [thumb setImageWithURL:[NSURL URLWithString:@"http://i.imgur.com/r4uwx.jpg"]];
}

此方法也包含在 AFNetworking 中,将下载图像,并在下载完成后在单元格中更新它。 文档和其他类似方法在这里

于 2013-10-29T19:54:29.107 回答