Как заставить CATiledLayer не блокировать основной поток

Я внедряю CATiledLayer в UIScrollView. В CATiledLayer у меня есть функция для рисования слоев следующим образом:

- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx {
    CGContextTranslateCTM(ctx, 0.0f, 0.0f);
    CGContextScaleCTM(ctx, 1.0f, -1.0f);

    CGRect box = CGContextGetClipBoundingBox(ctx);

    NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"urlhere"]];
    UIImage *image = [[UIImage alloc] initWithData:data];

    CGContextDrawImage(ctx, box, [image CGImage]);
    [image release];
    [data release];
}

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

По сути, мне просто нужно знать, как асинхронно загружать данные в сообщении рисования CATiledLayer.


person rickharrison    schedule 03.06.2010    source источник


Ответы (1)


Вы загружаете данные асинхронно, как и в любой другой ситуации, используя что-то вроде NSURLConnection. Когда загрузка будет завершена, скажите слою перерисовать, который затем вызовет -drawLayer:inContext: после чего вы просто захватите загруженное изображение. Другими словами, не загружайте свои данные в -drawLayer и не используйте -dataWithContentsOfURL, который является синхронным и блокирует по умолчанию.

person Matt Long    schedule 04.06.2010
comment
Итак, после того, как данные загружены и отображены на экране, я должен освободить UIImage? Если я уйду и вернусь, будет ли он все еще нарисован там? - person rickharrison; 04.06.2010
comment
Данные кэшируются, но вы не можете управлять кэшированием, поэтому ваш код должен ожидать, что drawLayer:inContext может вызываться повторно. - person JakubKnejzlik; 21.05.2014