Mac OS X: что вызывает вращающийся пляжный мяч?
Когда OS X решит дать вашему приложению крутящийся пляжный мяч? Что вы можете сделать при программировании приложения, чтобы избежать этого?
3 ответа
Оконный сервер покажет вращающийся курсор ожидания, когда самое переднее приложение или приложение, у которого есть окно под указателем мыши, не ответило на события от оконного сервера в течение определенного времени.
Чтобы избежать вращающегося курсора ожидания, приложение должно своевременно обслуживать события. Нет никакого способа обойти это оконное поведение сервера, и на то есть веская причина: приложения в Mac OS X никогда не должны реагировать на действия пользователя.
Причина в том, что ваше приложение блокирует пользовательский интерфейс. Как говорили другие авторы, оконный менеджер может заметить, что вы не обрабатывали события какое-то время, и создал этот пользовательский интерфейс.
Скорее всего, вы выполняете некоторые операции ввода-вывода (например, чтение или запись на диск или сетевые запросы) синхронно в потоке пользовательского интерфейса (по умолчанию). Хорошее эмпирическое правило, позволяющее поддерживать адаптивность вашего приложения (и, следовательно, избегать пляжного мяча), - никогда не выполнять синхронный ввод-вывод в потоке интерфейса. Вы можете либо использовать асинхронный ввод-вывод (API, которые принимают обратный вызов, выполняют работу в фоновом потоке, а затем уведомляют вас в потоке пользовательского интерфейса, когда они это сделали), либо вы можете использовать отдельный фоновый поток для выполнения этой работы.
Если вы не выполняете ввод-вывод, то вы, вероятно, находитесь в каком-то длинном цикле в потоке пользовательского интерфейса, который заставляет вас не отвечать на запросы. В этом случае либо оптимизируйте, либо удалите цикл, либо переместите его в фоновый поток.
Предполагая, что ваше приложение имеет достаточные аппаратные ресурсы (что не всегда так), нет никаких причин, по которым ваше приложение должно когда-либо играть в пляжный мяч. Если это так, выясните, какая часть кода блокирует пользовательский интерфейс (если он не интуитивно понятен, Shark.app пригодится) и переместите его в фоновый поток (или используйте другую стратегию для устранения паузы). К счастью, у Cocoa и Objective-C есть довольно хорошие инструменты для многопоточности, для начала посмотрите NSOperationQueue. У Apple также есть несколько хороших документов по настройке производительности, см. Этот вопрос для соответствующих ссылок.