Технические вопросы и ответы QA1637

CATiledLayer и графика UIKit

Q: Я использую a CATiledLayer когда у меня есть многократные представления об экране, в моем приложении и я иногда вижу неправильный рендеринг или катастрофические отказы, особенно. Что я могу сделать для предотвращения этого?

A: Я использую a CATiledLayer когда у меня есть многократные представления об экране, в моем приложении и я иногда вижу неправильный рендеринг или катастрофические отказы, особенно. Что я могу сделать для предотвращения этого?

Поэтому на iOS 4.0 и позже, можно переопределить -drawRect: и сделайте все свои получения как нормальные, но если Вы планируете поддерживать iOS до 4,0, необходимо все еще знать о проблемах, повышенных в этом документе.

CATiledLayer реализует его получение при помощи фонового потока для выборки содержания каждой мозаики, однако функции получения, предоставленные UIKit, полагаются на глобальный штабель контекста, и как таковой когда a CATiledLayer начинает представлять, использование любой из рисующих функций UIKIT может привести к состоянию состязания.

Практически то, что это означает, - то, что Вы не можете использовать методы рисования UIKIT при рисовании к a CATiledLayer, и Вы не можете сделать своего получения в a UIView -drawRect: метод. Вместо этого необходимо реализовать -drawLayer:inContext: и нарисуйте только Графику Ядра использования и другие ориентированные на многопотоковое исполнение функции, принимающие a CGContextRef предназначаться для получения к.

Если Ваш -drawRect: использование метода UIImageнарисуйте методы, UIColorметоды установки, любой строковый метод рисования от NSString(UIStringDrawing) или любой из UIRect или UIGraphics функции, предоставленные UIKit, тогда Ваш -drawLayer:inContext: метод должен быть переписан, чтобы избегать использования тех методов, и вместо этого использовать Базовую Графику непосредственно. Не все операции от NSString(UIStringDrawing) тривиально преобразовываются в Базовую Графику, таким образом, можно хотеть связаться с Технической поддержкой Разработчика.

Поскольку UIKit использует существование переопределения -drawRect: определить некоторую функциональность a UIView, необходимо все еще реализовать -drawRect: метод, но это ничего не должно делать (и не будет вызван вследствие Вашей реализации -drawLayer:inContext:). Пример корректной реализации a UIView это использует a CATiledLayer находится в Перечислении 1.

Перечисление 1  реализация a UIView подкласс, использующий a CATiledLayer для layerClass.

#import <QuartzCore/QuartzCore.h>
#import <UIKit/UIKit.h>
#import "MyTiledView.h"

+(Class)layerClass
{
    return [CATiledLayer class];
}

-(void)drawRect:(CGRect)r
{
    // UIView uses the existence of -drawRect: to determine if should allow its CALayer
    // to be invalidated, which would then lead to the layer creating a backing store and
    // -drawLayer:inContext: being called.
    // By implementing an empty -drawRect: method, we allow UIKit to continue to implement
    // this logic, while doing our real drawing work inside of -drawLayer:inContext:
}

-(void)drawLayer:(CALayer*)layer inContext:(CGContextRef)context
{
    // Do all your drawing here. Do not use UIGraphics to do any drawing, use Core Graphics instead.
}


История версии документа


ДатаПримечания
15.02.2011

Добавленный примечание об изменениях для iPhone OS 4.0.

08.09.2009

Новый документ, обсуждающий вопросы потокобезопасности при использовании CATiledLayer на iOS