Как удалить SKNode, не вызывая гонки данных?IOS

Программируем под IOS
Ответить
Anonymous
 Как удалить SKNode, не вызывая гонки данных?

Сообщение Anonymous »

Я пишу приложение для iOS с помощью SpriteKit, но обнаружил противоречивую информацию об удалении SKNode из его родительского элемента, что ставит меня в тупиковую ситуацию.
Состязания данных особенно важны описано в документации SpriteKit:

Если у вас возникла ошибка сегментации или другой тип сбоя, происходящий глубоко внутри структуры SpriteKit, велика вероятность, что ваш код изменяет объект SpriteKit вне обратных вызовов делегата сцены.

Поэтому я понимаю, что мне следует изменять (удалять) узлы только внутри этих обратных вызовов. Фактически, я постоянно сталкивался с гонками/сбоями/исключениями данных при запуске SKAction с блоком завершения, который удаляет узел в основной очереди. Даже само действие SKAction.removeFromParent выдает исключение и становится практически непригодным для использования.
Вызов SKNode.removeFromParent() в обратном вызове обновления SKScene вызывает вызов исключение и регистрирует консольное сообщение о том, что удаление узла разрешено только в основном потоке. Это противоречит документации, поэтому я чувствую в Apple какой-то забытый код.
Это противоречит другой части документации SpriteKit:

Все обратные вызовы SpriteKit для SKViewDelegate, SKSceneDelegate и SKScene выполняются в основном потоке, поэтому это безопасные места для доступа к узлам или управления ими.

Однако я могу доказать, что обратные вызовы SKScene НЕ вызываются в основном потоке, просто поместив точку останова в мой переопределенный метод SKScene.update(:). Они вызываются в некоторой последовательной очереди рендеринга SceneKit.
В моем приложении я использую SCNSceneRenderer.overlaySKScene с SKScene, который дополняет SCNScene. Вероятно, в SceneKit все работает по-другому, но это все равно сцена SpriteKit.
И что же теперь? Я не могу удалить узлы в обратном вызове обновления, поскольку он не вызывается в основной очереди. Я также не могу удалить узлы в основной очереди, поскольку это приводит к гонкам данных.
Решение № 1 – не удалять узлы в все, но это не совсем решение. Некоторые узлы, такие как SKShapeNode, имеют фиксированный кадр, который можно установить только во время инициализации. Я мог бы переместить их на скрытый узел «кладбища» или в узел кэша, но это будет всего лишь обходной путь для того, что должно работать «из коробки».
Решение № 2< /strong> предназначен для предотвращения гонок данных путем приостановки SCNView, затем ожидания завершения рендеринга последнего кадра и только после этого удаления узлов в основном потоке, а затем снова возобновления приостановки представления. Это обременительно и в первую очередь не должно быть необходимым. И для этого мне нужно найти несколько неподвижных кадров (черный переход с плавным затуханием?), где я могу приостановить просмотр, не раздражая пользователей.
Кто-нибудь сталкивался с такой проблемой и нашел другой способ?
У меня такое ощущение, что Apple реализовала SCNSceneRenderer.overlaySKScene в iOS 8, а затем в ближайшие годы внесла другие изменения и забыла об этом.

Подробнее здесь: https://stackoverflow.com/questions/786 ... -data-race
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «IOS»