#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];
, чтобы убедиться, что это происходит в основном потоке.