Objective C Пользовательские Ленивые Загрузка Изображения UITableView Ячейки - PullRequest
2 голосов
/ 31 января 2012

Первая загрузка удаленных изображений в приложение для iPhone, и вам нужна помощь в оптимизации процесса.В настоящее время я получил изображение, если оно не существует, и поместил его в кэш.Основные цели:

  • загружать изображения только при необходимости.
  • сохранять изображения для будущего использования, чтобы сократить потребление данных и позволить пользователю иметь несколько функциональное приложение, когда он не подключенв Интернет.

Я просто не думаю, что делаю это достаточно хорошо.

Вот фрагмент кода в tableView: cellForRowAtIndexPath:

MVImageCell * cell = (MVImageCell *)[tableView dequeueReusableCellWithIdentifier:@"PicsAndVideosCell"];

// empty cell
cell.imageView.image = nil;
cell.textLabel.text = nil;
cell.detailTextLabel.text = nil;

// set cell properties
cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
cell.textLabel.numberOfLines = 2;
cell.imageView.contentMode = UIViewContentModeScaleAspectFit;
cell.imageView.frame = CGRectMake(15, 6, 58, 58);
cell.imageView.layer.cornerRadius = 6;
cell.imageView.layer.masksToBounds = YES;

Photoset * sfc = [self.myarray objectAtIndex:indexPath.row];
cell.cid = sfc.sfcid;
cell.ctitle = sfc.title;
cell.cimg = sfc.cover;

cell.textLabel.text = sfc.title;
cell.detailTextLabel.text = sfc.date;

// set cell image
MVImage * thumb = [[MVImage alloc] init];
NSString * retina = ([[MVProject sharedInstance] settings_retina]) ? @"2" : @"";
if ([NSKeyedUnarchiver unarchiveObjectWithData:[[NSUserDefaults standardUserDefaults] objectForKey:[NSString stringWithFormat:@"Settings_SFCCovers%@_%@", retina, cell.cid]]]) {
    thumb = [NSKeyedUnarchiver unarchiveObjectWithData:[[NSUserDefaults standardUserDefaults] objectForKey:[NSString stringWithFormat:@"Settings_SFCCovers%@_%@", retina, cell.cid]]];

    [cell.imageView setImage:[MVImage imageWithImage:[[UIImage alloc] initWithData:thumb.data] covertToWidth:58.0f covertToHeight:58.0f]];
    [cell bringSubviewToFront:[cell.imageView superview]];
} else {
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
    dispatch_async(queue, ^{
        dispatch_sync(dispatch_get_main_queue(), ^{
            thumb.data = [NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@", cell.cimg]]];
            thumb.title = cell.ctitle;
            [[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:thumb] forKey:[NSString stringWithFormat:@"Settings_SFCCovers%@_%@", retina, cell.cid]];

            [cell.imageView setImage:[MVImage imageWithImage:[[UIImage alloc] initWithData:thumb.data] covertToWidth:58.0f covertToHeight:58.0f]];
            [cell bringSubviewToFront:[cell.imageView superview]];
        });
    });
}

return cell;

Стоит ли использовать базу данных SQLite вместо NSUserDefaults?

У меня также возникают проблемы с асинхронной загрузкой.Я чувствую, что это должно выглядеть так:

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
    thumb.data = [NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@", cell.cimg]]];
    thumb.title = cell.ctitle;
    [[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:thumb] forKey:[NSString stringWithFormat:@"Settings_SFCCovers%@_%@", retina, cell.cid]];

    dispatch_sync(dispatch_get_main_queue(), ^{
        [cell.imageView setImage:[MVImage imageWithImage:[[UIImage alloc] initWithData:thumb.data] covertToWidth:58.0f covertToHeight:58.0f]];
        [cell bringSubviewToFront:[cell.imageView superview]];
    });
});

Но это, очевидно, сохраняет неправильные данные изображения в место назначения NSUserDefault.

Любая помощь по этому поводу, указатели на мой стиль кодирования ивсе остальное очень ценится.

Спасибо!

Ответы [ 2 ]

5 голосов
/ 31 января 2012

Просто бегло взглянем на ваш код - кажется, что вы помещаете блоки в асинхронные очереди, но вы вызываете код UI в этих блоках.

Вы должны запускать код пользовательского интерфейса только в главном потоке.

Что касается решения - взгляните на некоторые реализации с открытым исходным кодом, чтобы либо дать вам представление о том, что вы должны делать, либо просто использовать их напрямую.

Один из них - AsyncImageView на Github.

Есть и другие, которые вызовет быстрый поиск.

2 голосов
/ 31 января 2012

2 предложения: 1. Не храните изображения в NSUserDefaults, что больше подходит для пользовательских предпочтений, таких как строки.

  1. Не выполняйте операцию разархивирования дважды.Просто сделайте это, затем проверьте результаты.

Замените это:

if ([NSKeyedUnarchiver unarchiveObjectWithData:[[NSUserDefaults standardUserDefaults] objectForKey:[NSString stringWithFormat:@"Settings_SFCCovers%@_%@", retina, cell.cid]]]) {
thumb = [NSKeyedUnarchiver unarchiveObjectWithData:[[NSUserDefaults standardUserDefaults] objectForKey:[NSString stringWithFormat:@"Settings_SFCCovers%@_%@", retina, cell.cid]]];

На это:

thumb = [NSKeyedUnarchiver unarchiveObjectWithData:[[NSUserDefaults standardUserDefaults] objectForKey:[NSString stringWithFormat:@"Settings_SFCCovers%@_%@", retina, cell.cid]]];
 if ( thumb ) ... 
...