CATiledLayer запрашивает одну и ту же плитку несколько раз - PullRequest
2 голосов
/ 03 апреля 2011

Пожалуйста, посмотрите этот простой пример CATiledLayer https://github.com/seanhess/CATiledLayer-Example

Он состоит из одного viewController с такой иерархией:

view: (frame = window size)
    scrollView: (frame = window size, content size = 200 x 4000)
        contentView: (frame = content size = 200 x 4000, tile size = 100 x 100)

Слой представления содержимого был переопределен как CATiledLayer.

Если вы запустите связанный код, вы увидите, что плитки с одним и тем же прямоугольником запрашиваются несколько раз . Это происходит как при первом запуске кода, так и при прокрутке.

Переключиться на ветку «один столбец» - это происходит только при инициализации, а не при прокрутке вниз.

Переключиться на ветку "default-tile-size" - это происходит только при инициализации, но очень редко (вам нужно запустить его несколько раз, прежде чем это произойдет)

Я пытаюсь написать код в drawLayer:inContext:, который находит правильные данные и рисует их. Это может быть дорого, и я не хочу делать это более одного раза.

Есть идеи, что происходит? Что я мог сделать по-другому?

Ответы [ 5 ]

2 голосов
/ 11 июля 2012

Это ошибка в IOS. Это происходит, когда ЦП является двухъядерным, в этом случае есть два потока, каждый из которых запрашивает каждый тайл. Это означает, что ошибка присутствует в симуляторе и на iPhone 4S, но не на других моделях iPhone. Я предполагаю, что это также будет присутствовать на двухъядерных iPad.

Я уже давно сообщал об ошибке в Apple (для симулятора), а недавно снова (для iPhone 4S). У Apple недавно создалось впечатление, что они решили это в IOS 6.

1 голос
/ 27 сентября 2014

Очень хорошо решено здесь:

https://stackoverflow.com/a/8783396/341994

Проблема в том, что (по крайней мере, в моем тестировании) drawRect: вызывается одновременно в двух потоках.Зарегистрировавшись, я вижу, как отдельные строки моего кода выполняются дважды, прежде чем мы перейдем к следующей строке, которая также выполняется дважды!Ведение журнала показывает, что это происходит потому, что один поток выполняет строку, а затем другой поток выполняет ту же строку - и затем они оба переходят к следующей строке.

Это настолько неприятно, насколько это возможно.Решение состоит в том, чтобы обернуть весь интерьер drawRect: в dispatch_sync в последовательной очереди.

0 голосов
/ 04 мая 2011

Разве это не из-за setLevelsOfDetailBias? Когда я оставляю все стандартным, плитки отображаются только один раз (тестирование на устройстве). Но когда я устанавливаю levelofdetailbias на 2, плитки загружаются несколько раз. Я думаю, это связано с тем, что CATiledLayer только начинает кэшировать дополнительные уровни детализации, когда устройство находится в режиме ожидания.

0 голосов
/ 09 ноября 2011

В конце концов, ответы не сработали.Тем не менее, довольно просто сделать так, чтобы ваш метод делегата знал, нарисовал ли он этот цикл или нет.

0 голосов
/ 28 апреля 2011

Вы пробовали свой код на устройстве?Я постоянно вижу это поведение в симуляторе, но не на своем iPad 1. Я только что попробовал это снова в приложении, которое отображает большое мозаичное изображение.Мой размер плитки равен 256, и на устройстве мой метод drawRect: вызывается 12 раз, то есть сколько плиток находится на экране.В симуляторе метод вызывается от 20 до 23 раз, при этом все плитки, кроме последних, отрисовываются дважды.

...