Оригинальный вопрос ...............................................
Если вы являетесь опытным пользователем drawRect, вы будете знать, что drawRect, конечно же, не будет работать, пока "вся обработка не будет завершена".
setNeedsDisplay помечает представление как недействительное и ОС и в основном ждет, пока не будет выполнена вся обработка.Это может приводить в бешенство в обычной ситуации, когда вы хотите иметь:
- контроллер представления 1
- запускает некоторую функцию 2
- , которая постепенно увеличивается на 3
- создает все более и более сложные графические объекты и 4
- на каждом шаге, вы устанавливаетеNeedsDisplay (неправильно!) 5
- до тех пор, пока вся работа не будет выполнена 6
Конечно, когда вы делаете выше 1-6, все, что происходит, это то, что drawRect запускается только один раз после шага 6.
Ваша цель - обновить представление в точке 5. Что делать?
Решение исходного вопроса ..............................................
Одним словом, выможет (A) фон большая картина, и вызвать на первый план для обновления пользовательского интерфейса или (в), возможно, спорное есть четыре«немедленные» методы предложили не использовать фоновый процесс.Для результата того, что работает, запустите демонстрационную программу.У него есть #defines для всех пяти методов.
Действительно поразительное альтернативное решение, представленное Томом Свифтом ..................
Том Свифт объяснил удивительную идею простого манипулирования циклом выполнения .Вот как вы запускаете цикл выполнения:
[[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate: [дата NSDate]];
Это действительно удивительный пример разработки.Конечно, нужно быть очень осторожным при манипулировании циклом выполнения, и, как многие отмечали, этот подход предназначен исключительно для экспертов.
Странная проблема, которая возникает ..............................................
Несмотря на то, что некоторые методы работают, они на самом деле не «работают», потому что есть странный прогрессирующий замедляющий артефакт, который вы четко увидите в демоверсии.
Прокрутите до «ответа»Я вставил ниже, показывая вывод консоли - вы можете видеть, как он постепенно замедляется.
Вот новый вопрос SO:
Таинственная проблема "прогрессивного замедления" в цикле выполнения / 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
Вы можете сами увидеть, какие методы работают, а какие нет.
Вы можете увидеть причудливое «прогрессивное замедление».почему это происходит?
Так что подавляющая вещь - это странное «прогрессивное замедление»: на каждой итерации по неизвестным причинамВремя, затраченное на петлю смерти.Обратите внимание, что это относится как к тому, чтобы делать это «правильно» (фоновый вид), так и к использованию одного из «непосредственных» методов.
Практические решения ........................
Для тех, кто читает в будущем, если вы действительно не можете заставить его работать в производственном коде из-за «загадочного прогрессирующего замедления» ... Felz и Void представили поразительные решения в другом конкретном вопросе, надеюсь, этопомогает.