Я не совсем понимаю, как CALayer display
и drawInContext
относятся к drawRect
на вид.На iOS, setNeedsDisplay действительно не вызывает drawRect для вызова ... если показ CALayer или drawInContext окончательно не вызовет drawRect?
Если у меня есть NSTimer, который устанавливает [self.view setNeedsDisplay]
каждые 1 секунду, а затем drawRect
называют каждую 1 секунду, как показан оператором NSLog внутри drawRect
.
Но если я подклассию CALayer и использую это для представления, если я делаю метод display
пустым, то теперь drawRect
никогда не вызывается. Обновление: Но display
вызывается каждые 1 секунду, как показано в инструкции NSLog.
Если я удалю этот пустой метод display
и добавлю пустой метод drawInContext
, снова drawRect
никогда не вызывается. Обновление: Но drawInContext
вызывается каждые 1 секунду, как показано в инструкции NSLog.
Что именно происходит? Кажется, что display
может выборочно позвонить drawInContext
и drawInContext
может выборочно каким-то образом позвонить drawRect
(как?), Но какова реальная ситуация здесь?
Update: есть более ключ к ответу:
Я изменил CoolLayer.m
код на следующее:
-(void) display {
NSLog(@"In CoolLayer's display method");
[super display];
}
-(void) drawInContext:(CGContextRef)ctx {
NSLog(@"In CoolLayer's drawInContext method");
[super drawInContext:ctx];
}
Так, скажем, если есть луна (как круг, нарисованный Core Graphics) в местоположении (100,100) в представлении, и теперь я меняю его на местоположение (200,200), естественно, я вызову [self.view setNeedsDisplay]
, и теперь у CALayer не будет никакого кэша для нового изображения вида , Как мой drawRect
диктует, как теперь должна отображаться Луна.
Тем не менее, точка входа CALayer-х display
, а затем CALayer-х drawInContext
: Если установить точку останова на drawRect
, стек вызовов показывает:
Таким образом, мы можем видеть, что CoolLayer-х display
является вошел первым, и он переходит в CALayer display
, а затем в CoolLayer drawInContext
, а затем в CALayer drawInContext
, хотя в этой ситуации такой кеш для нового изображения не существует.
Затем, наконец, drawInContext
CALayer вызывает делегат drawLayer:InContext
. Делегат - это представление (FooView или UIView) ... и drawLayer:InContext
- это реализация по умолчанию в UIView (поскольку я не переопределял ее). Наконец, drawLayer:InContext
звонит drawRect
.
Итак, я угадываю два момента: почему он входит в CALayer, хотя для изображения нет кеша? Потому что благодаря этому механизму изображение рисуется в контексте и, наконец, возвращается к display
, а CGImage создается из этого контекста, а затем он теперь устанавливается как новое кэшированное изображение. Так CALayer кэширует изображения.
Другое дело, что я не совсем уверен: если [self.view setNeedsDisplay]
всегда вызывает drawRect
, то когда можно использовать кешированное изображение в CALayer? Может быть ... в Mac OS X, когда другое окно закрывает окно, и теперь верхнее окно удаляется. Теперь нам не нужно звонить drawRect
, чтобы перерисовать все, но можно использовать кешированное изображение в CALayer. Или в iOS, если мы остановим приложение, сделаем что-то еще и вернемся к приложению, тогда можно использовать кэшированное изображение вместо того, чтобы звонить drawRect
. Но как отличить эти два типа «грязных»? Один из них - «неизвестный грязный» - что луну нужно перерисовать, как это продиктовано логикой drawRect
(она может также использовать случайное число для этой координаты). Другие типы грязных - это то, что они были закрыты или исчезли, и теперь их нужно повторить.
Как работает CALayer? –
В документации явно указано, что 'setNeedsDisplay' работает только для графиков UIKit и Core Graphics, я считаю, что обновление для грязных просмотров действительно для обоих. Помните, что это недопустимо для 'CAEAGLLayer', как указано в документации. –
вопрос в том, что мы используем 'setNeedsDisplay', но переопределяем метод CALayer, тогда' drawRect' не вызывается и почему? –