Оригинальный вопрос...............................................
Если вы являетесь продвинутым пользователем drawRect, вы узнаете, что, конечно, drawRect фактически не будет работать до тех пор, пока "вся обработка не будет завершена".
setNeedsDisplay помещает представление как недействительное и ОС, и в основном ждет, пока вся обработка не будет выполнена. Это может приводить в бешенство в общей ситуации, в которой вы хотите:
- контроллер вида 1
- запускает некоторую функцию 2
- который пошагово 3
- создает все более сложные изображения и 4
- на каждом шаге вы устанавливаетеNeedsDisplay (неверно!) 5
- пока вся работа не будет выполнена 6
Конечно, когда вы делаете вышеприведенное 1-6, все, что происходит, это то, что drawRect запускается только один раз после шага 6.
Ваша цель - обновить представление в точке 5. Что делать?
Решение первоначального вопроса..............................................
Одним слова, вы можете (A) фон большой картины, и вызвать на первый план для обновления пользовательского интерфейса или (В), возможно, спорном есть четыре "немедленный 'методы, которые не используют фоновый процесс. Для результата работы запустите демонстрационную программу. Он имеет #defines для всех пяти методов.
Поистине поразительное альтернативное решение, введенное Томом Свифтом..................
Том Свифт объяснил удивительную идею довольно простого манипулирования циклом выполнения. Здесь, как вы запускаете цикл выполнения:[[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate: [NSDate date]];
Это поистине удивительная часть техники. Разумеется, при манипулировании циклом запуска следует проявлять особую осторожность, и многие из них указали на этот подход строго для экспертов.
Необычная проблема, которая возникает..........
Несмотря на то, что ряд методов работает, они фактически не работают, потому что есть необычный артефакт прогрессивного замедления, который вы увидите в демо.
Прокрутите до "ответ", который был вставлен ниже, показывая вывод консоли - вы можете видеть, как он постепенно замедляется.
Здесь новый вопрос SO:
Таинственное "постепенное замедление" проблема в run loop/drawRect
Вот V2 демонстрационного приложения...
http://www.fileswap.com/dl/p8lU3gAi/stepwiseDrawingV2.zip.html
Вы увидите, что он тестирует все пять методов,
#ifdef TOMSWIFTMETHOD
[self setNeedsDisplay];
[[NSRunLoop currentRunLoop]
runMode:NSDefaultRunLoopMode beforeDate:[NSDate date]];
#endif
#ifdef HOTPAW
[self setNeedsDisplay];
[CATransaction flush];
#endif
#ifdef LLOYDMETHOD
[CATransaction begin];
[self setNeedsDisplay];
[CATransaction commit];
#endif
#ifdef DDLONG
[self setNeedsDisplay];
[[self layer] displayIfNeeded];
#endif
#ifdef BACKGROUNDMETHOD
// here, the painting is being done in the bg, we have been
// called here in the foreground to inval
[self setNeedsDisplay];
#endif
-
Вы можете сами убедиться, какие методы работают, а какие нет.
-
вы можете увидеть странное "прогрессивное замедление". почему это происходит?
-
Вы можете увидеть спорный метод TOMSWIFT, нет фактически никаких проблем с отзывчивостью. нажмите для ответа в любое время. (но все же причудливая проблема "постепенного замедления" )
Таким образом, подавляющая вещь - это странное "прогрессивное замедление": на каждой итерации по неизвестным причинам время, затрачиваемое на цикл, уменьшается. Обратите внимание, что это относится как к "правильному" (фоновой), так и к использованию одного из "непосредственных" методов.
Практические решения........................
Для тех, кто читает в будущем, если вы на самом деле не можете заставить это работать в производственном коде из-за "постепенного замедления тайны"... Felz и Void каждый из них представил поразительные решения в другом конкретном вопросе, надеюсь, что это помогает.