Использование block или NSOperation для загрузки изображения?

#ios #multithreading #objective-c-blocks #nsoperation #grand-central-dispatch

#iOS #многопоточность #objective-c-блоки #nsoperation #grand-central-dispatch

Вопрос:

Мне нужно знать, лучше ли использовать NSOperation или Block для загрузки большого количества изображений в UIScrollView? Я создаю все Imageview и размещаю каждый UIImageView в нужном положении в прокрутке.

Чтобы избежать предупреждения о памяти, я выбираю загружать изображение один раз за раз. Моя идея состоит в том, чтобы создать своего рода очередь и вставить все изображения для загрузки в очередь. Я должен использовать block или NSOperation для этого?

Ответ №1:

В tableView:cellForRowAtIndexPath: вы можете использовать GCD (Grand Central Dispatch) для асинхронной загрузки изображений.

Вот так:

 static NSString *CellIdentifier = @"ImageCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                   reuseIdentifier:CellIdentifier] autorelease];
}
NSString *imagepath = //get path to image here
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
    UIImage *image = [UIImage imageWithContentsOfFile:imagePath];
    dispatch_sync(dispatch_get_main_queue(), ^{
        [[cell imageView] setImage:image];
        [cell setNeedsLayout];
    });
});
return cell;
  

Редактировать: Для лучшего ответа посмотрите сессию 211 WWDC ’12 — «Создание параллельных пользовательских интерфейсов на iOS» (спасибо @ sc0rp10n!)

Комментарии:

1. Кто-то проголосовал против без объяснения причин. Если вы случайно увидите это, не могли бы вы объяснить, что не так с этим ответом?

2. что произойдет, если вы прокручиваете вверх и вниз, а строки появляются на экране и исчезают с него? При использовании этого метода не будут ли сначала отображаться неправильные изображения, которые в конечном итоге будут заменены правильным изображением? (К вашему сведению, я не голосовал против)

3. Нет, если вы создаете путь к изображению, который ссылается на правильное изображение, на основе пути индекса.

4. Это решение неверно. Ячейка, которая будет получать изображение асинхронно, могла быть переработана в течение этого периода времени (или даже выпущена). Вам следует взглянуть, например, на AFNetworking ( github.com/AFNetworking/AFNetworking ) и категория UIImageView AFNetworking.

5. О новом способе реализации этого в iOS 6 смотрите новое видео WWDC2012: Сессия 211 — Построение параллельных пользовательских интерфейсов на iOS. Это демонстрирует правильную отмену загрузки изображения в переработанные ячейки (примерно с 38:00 до 45:00).

Ответ №2:

Если вам нужна очередь, то NSOperationQueue (и, следовательно, NSOperations) — разумная вещь для использования 🙂

Комментарии:

1. в чем основное отличие от использования GDC и блоков?

2. Почти наверняка нет — бьюсь об заклад, NSOperation использует GCD под капотом. Я просто считаю, что работать с NSOperations проще 🙂

3. Я могу добавить изображение в superview внутри объекта NSOperation??

4. Вероятно, нет — NSOperation выполняется в фоновом потоке. однако вы можете использовать что-то вроде [myView performSelectorOnMainThread:@selector(addSubview:) withObject:imageView waitUntilDone:YES]; , чтобы убедиться, что это происходит в основном потоке.