Comments 31
так пустой же цикл, вот оптимизатор его и выпилил в релизе.
+13
Он его не просто выпилил. NSLog до этого цикла выполняется, а после него — никогда. Т.е. он в нем виснет.
+3
Оптимизатор перенес переменную из памяти в регистры. Как результат — изменение значения в памяти другим потоком ничего не дает. Почитайте про специальный модификатор volatile — поймете суть проблемы.
+2
Хорошо. Volatile, так volatile. Спасибо за него, кстати.
Но кто-нибудь может объяснить, почему этого в debug build не происходит, а только в release? Перепроверил все флаги и build settings — все одинаково для обеих конфигураций
Но кто-нибудь может объяснить, почему этого в debug build не происходит, а только в release? Перепроверил все флаги и build settings — все одинаково для обеих конфигураций
+1
Это баг в компиляторе же, ты не понял
0
Объявить isRendering как volatile?
+3
Цикл while выполняется пока isRendering == NO
Если isRendering изменяется в другом потоке без volatile — то не детерминированное количество раз.
Никакого ограничения на количество итераций while нет и быть не может.
А описание проблемы настолько путанное, что локализовать ее тяжело. Возможно, вы изобрели велосипед вместо очереди сообщений.
Если isRendering изменяется в другом потоке без volatile — то не детерминированное количество раз.
Никакого ограничения на количество итераций while нет и быть не может.
А описание проблемы настолько путанное, что локализовать ее тяжело. Возможно, вы изобрели велосипед вместо очереди сообщений.
+5
А разве за
while (!isRendering) {
}
ещё не обрывают руки? Есть же мониторы, семафоры, мьютексы…
while (!isRendering) {
}
ещё не обрывают руки? Есть же мониторы, семафоры, мьютексы…
+14
Здесь идет работа в рамках одного потока. Но, насколько я понимаю, поставщиком задач является другой поток. В целом, все сводится к задаче «производители/потребители», которая на iOS решается с помощью GCD и sequential очереди задач. Ну, или NSOperationQueue для слабых духом.
+2
NSOperationQueue начиная с iOS 4 основана на GCD как раз
0
Возможно, я не слишком копался в ее кишках. GCD показался мне в разы удобнее и я сразу забыл про эту обертку.
0
не возможно, а вполне явно написано в документации :)
0
Я бы сказал «определенно», но не заглядывал в документацию, а привычки верить людям на слово не имею :)
+1
За подсказку с NSLock спасибо, в авральном режиме работаем, вылетела из головы эта фича.
По поводу GCD: изначально все писалось на нем, были красивые конструкции вроде dispatch_group_wait и так далее. Но у GCD проблема с рендерингом вьюшек. Поэтому был создан свой класс, унаследованный от NSThread и там была реализована человеческая очередь на выполнение.
Да, вы меня сейчас забросаете помидорами за использование UIKit вне главного потока, но все же это не критично. Ибо главное не обращаться к одной и той же вьюшке из конкурирующих потоков.
По поводу GCD: изначально все писалось на нем, были красивые конструкции вроде dispatch_group_wait и так далее. Но у GCD проблема с рендерингом вьюшек. Поэтому был создан свой класс, унаследованный от NSThread и там была реализована человеческая очередь на выполнение.
Да, вы меня сейчас забросаете помидорами за использование UIKit вне главного потока, но все же это не критично. Ибо главное не обращаться к одной и той же вьюшке из конкурирующих потоков.
0
У GCD проблемы нет, это у вас проблемы с рендерингом.
Правильный рендеринг на GCD выглядит так:
1. Создаем ContextRef через CreateBitmapContext
2. Рисуем в него как в любой нормальный контекст
3. Создаем из контекста ImageRef
4. Передаем его в основной поток и
4.1. Ставим его в view.layer.contents
4.2. Преобразуем в UIImage и используем в слое-подложке на базе ImageView
А то, что вы делаете — это непонятно что. И оно может отвалиться в любой момент, причем совершенно недетерминированно.
Правильный рендеринг на GCD выглядит так:
1. Создаем ContextRef через CreateBitmapContext
2. Рисуем в него как в любой нормальный контекст
3. Создаем из контекста ImageRef
4. Передаем его в основной поток и
4.1. Ставим его в view.layer.contents
4.2. Преобразуем в UIImage и используем в слое-подложке на базе ImageView
А то, что вы делаете — это непонятно что. И оно может отвалиться в любой момент, причем совершенно недетерминированно.
+2
Вообще предпочитаю не обращаться к главному потоку, чтобы не блокировать UI
Да, у GCD во время создания контекста (рендерил пдф) я тоже ловил невнятные и непонятные ошибки, вроде context is null, и cannot restore null context.
Да, у GCD во время создания контекста (рендерил пдф) я тоже ловил невнятные и непонятные ошибки, вроде context is null, и cannot restore null context.
0
Вот именно, что два потока. И этот поток тупо жрёт ресурсы.
Любые инструменты, хоть для слабых, хоть для сильных, но не пустые циклы.
Любые инструменты, хоть для слабых, хоть для сильных, но не пустые циклы.
+1
и GCD, чтоб вручную треды не городить
+1
По симптомам — скорее всего компилятор действительно выбросил этот цикл при оптимизации. Тогда вам совершенно необязательно вставлять в цикл sleep, достаточно будет любого выполняемого кода, чтобы компилятор не счел, что цикл ничего не делает. Это если вам именно припекает поскорей залить продукт в App Store.
А вообще в свободное время нужно бы переделать это добро на GCD или NSOperation. Чтобы быстро въехать, что к чему, можно посмотреть эпловое видео, если английский позволяет (https://developer.apple.com/videos/wwdc/2012/, например см. сессию 712)
А вообще в свободное время нужно бы переделать это добро на GCD или NSOperation. Чтобы быстро въехать, что к чему, можно посмотреть эпловое видео, если английский позволяет (https://developer.apple.com/videos/wwdc/2012/, например см. сессию 712)
+1
По заголовку уже догадывался, что компилятор выбросил цикл.
Зашел почитать комментарии — так и вышло.
Зашел почитать комментарии — так и вышло.
+3
Правило что-ли в PVS-Studio сделать на такие циклы… Уже сколько раз видел аналогичные вопросы.
0
А вы dead code разве не репортите? А вообще, ИМХО, замечательный пример необходимости образования — не верю, что про такие вещи в ВУЗ'ах не рассказывают совсем.
+2
Dead code — понятие растяжимое. Если имеется в виду бессмысленный код, то что-то ловим, что-то нет. Многий бессмысленный код это продукт использования разнообразных макросов. Таких, например, как UNREFERENCED_PARAMETER. Если речь идёт о недостижимом коде, то с этой задачей хорошо справляются компиляторы. Пока не видно смысла дублировать эту функциональность.
0
Sign up to leave a comment.
Странности с циклами: в debug работает, в release нет