Я пишу приложение для 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
Как удалить SKNode, не вызывая гонки данных? ⇐ IOS
Программируем под IOS
-
Anonymous
1719397931
Anonymous
Я пишу приложение для iOS с помощью SpriteKit, но обнаружил противоречивую информацию об удалении SKNode из его родительского элемента, что ставит меня в тупиковую ситуацию.
Состязания данных особенно важны описано в документации SpriteKit:
Если у вас возникла ошибка сегментации или другой тип сбоя, происходящий глубоко внутри структуры SpriteKit, велика вероятность, что ваш код изменяет объект SpriteKit вне обратных вызовов делегата сцены.
Поэтому я понимаю, что мне следует изменять (удалять) узлы только внутри этих обратных вызовов. Фактически, я постоянно сталкивался с гонками/сбоями/исключениями данных при запуске SKAction с блоком завершения, который удаляет узел в основной очереди. Даже само действие SKAction.removeFromParent выдает исключение и становится практически непригодным для использования.
Вызов SKNode.removeFromParent() в обратном вызове обновления SKScene вызывает вызов исключение и регистрирует консольное сообщение о том, что удаление узла разрешено только в основном потоке. Это противоречит документации, поэтому я чувствую в Apple какой-то забытый код.
Это противоречит другой части документации SpriteKit:
Все обратные вызовы SpriteKit для SKViewDelegate, SKSceneDelegate и SKScene выполняются в основном потоке, поэтому это безопасные места для доступа к узлам или управления ими.
Однако я могу доказать, что обратные вызовы SKScene [b]НЕ вызываются в основном потоке[/b], просто поместив точку останова в мой переопределенный метод SKScene.update(:). Они вызываются в некоторой последовательной очереди рендеринга SceneKit.
В моем приложении я использую SCNSceneRenderer.overlaySKScene с SKScene, который дополняет SCNScene. Вероятно, в SceneKit все работает по-другому, но это все равно сцена SpriteKit.
И что же теперь? Я [b]не могу удалить узлы в обратном вызове обновления[/b], поскольку он не вызывается в основной очереди. Я также [b]не могу удалить узлы в основной очереди[/b], поскольку это приводит к гонкам данных.
[b]Решение № 1[/b] – не удалять узлы в все, но это не совсем решение. Некоторые узлы, такие как SKShapeNode, имеют фиксированный кадр, который можно установить только во время инициализации. Я мог бы переместить их на скрытый узел «кладбища» или в узел кэша, но это будет всего лишь обходной путь для того, что должно работать «из коробки».
Решение № 2< /strong> предназначен для предотвращения гонок данных путем приостановки SCNView, затем ожидания завершения рендеринга последнего кадра и только после этого удаления узлов в основном потоке, а затем снова возобновления приостановки представления. Это обременительно и в первую очередь не должно быть необходимым. И для этого мне нужно найти несколько неподвижных кадров (черный переход с плавным затуханием?), где я могу приостановить просмотр, не раздражая пользователей.
Кто-нибудь сталкивался с такой проблемой и нашел другой способ?
У меня такое ощущение, что Apple реализовала SCNSceneRenderer.overlaySKScene в iOS 8, а затем в ближайшие годы внесла другие изменения и забыла об этом.
Подробнее здесь: [url]https://stackoverflow.com/questions/78671852/how-to-remove-sknode-without-causing-a-data-race[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия