вопросы iOS 4 GCD

Я посмотрел на некоторые презентации, формируют 2010 WWDC и также читают большинство документов о блоках и параллелизме и имеют несколько вопросов относительно использования блоков с последовательными очередями в Центральной Отправке. У меня есть проект iOS 4, который имеет scrollview и словарь данных изображения - URL к изображениям и так далее. Я хочу использовать GCD и блоки, чтобы загрузить изображения и поместить их в мой scrollview таким образом не блокирование основного потока. Я написал следующий код, который, кажется, работает:

for (NSDictionary* dict in images)
{
     dispatch_async(image_queue, ^{

           NSString* urlString = [dict objectForKey:@"url"];
           NSURL* url = [NSURL URLWithString:urlString];
           NSData* imageData = [[NSData alloc] initWithContentsOfURL:url];
           UIImage* image = [UIImage imageWithData:imageData];
           UIImageView* imageView = // initialize imageView with image;      

           dispatch_async(dispatch_get_main_queue(), ^{
                [self.scrollView addSubview:imageView];
           });
           [imageData release];
      });
}

У меня есть два вопроса:

  1. Согласно руководству параллелизма я не должен получать переменные от объема включения, которые не являются скалярными типами - в моем коде, я получаю dict, который является NSDictionary* объект. Если мне не разрешают получить его, как я должен затем написать код? Блок только получает переменные от объема включения, которые на самом деле используются?

  2. Что происходит, если я покидаю текущий ViewController, прежде чем все изображения будут выбраны через последовательную очередь отправки? Я не думаю, что они знают, что ViewController, который создал их, ушел поэтому, что происходит, когда они выполняют обработчик завершений, где я вставляю представления изображения в свой scrollview на основном потоке? Это вызывает ошибку или что? И как я могу отменить какие-либо остающиеся операции на последовательной очереди, когда мой ViewController исчезает?

С уважением,

6
задан nevan king 11 August 2012 в 18:31
поделиться

1 ответ

  1. Хотя это мелочь, это важно для понимания того, что вам пытается сказать руководство по параллелизму: указатели - это скалярные типы. Таким образом, вы можете захватывать указатели внутри блоков сколько угодно ... НО вы должны знать время жизни памяти, на которую они указывают! NSDictionary * - это своего рода идентификатор, и когда вы ссылаетесь на идентификатор в блоке, среда выполнения берет на себя ответственность за сохранение идентификатора, если блок копируется (что происходит с помощью dispatch_async ()), а затем освобождает его, когда блок сам освобожден. И да, блок захватывает только те переменные, на которые в нем есть ссылки.

  2. Поскольку теперь вы знаете, что асинхронный блок сохранил себя, должно быть ясно (э), что (ошибки управления памятью по модулю) ваш ViewController не может «исчезнуть», пока блок не будет выполнен. Так что сбой не произойдет, но вы правы, заметив, что вам действительно нужен способ отменить этот вид асинхронной работы, когда вы на самом деле больше не планируете использовать результаты. Один простой, но эффективный шаблон - поставить тест в начале вашего асинхронного блока, который проверяет, нужно ли выполнять работу.

10
ответ дан 8 December 2019 в 17:18
поделиться