Я создаю простое приложение говорящего/слушающего, которое получает данные OSC через UDP. Я использую модуль OSCKit, который сам использует библиотеку CocoaAsyncSocket для внутренней связи UDP. Когда я прослушиваю определенный порт для получения данных от другого программного обеспечения, поддерживающего OSC, я регистрирую полученные команды в файле NSTextView
. Проблема в том, что иногда я получаю тысячи сообщений за очень короткий промежуток времени (EDIT: я просто добавил счетчик, чтобы увидеть, сколько сообщений я получаю. Я получил более 14000 всего за несколько секунд, и это это всего лишь один движущийся объект в моей программе). Невозможно предсказать, когда это произойдет, поэтому я не могу заблокировать объект textStorage
объекта NSTextView
, чтобы он не отправлял все свои уведомления для обновления пользовательского интерфейса. Данные обрабатываются с помощью функции обратного вызова делегата.
Так как же обойти это ограничение?
///Handle incoming OSC messages
func handle(_ message: OSCMessage!) {
print("OSC Message: \(message)")
let targetPath = message.address
let args = message.arguments
let msgAsString = "Path: \"\(targetPath)\"\nArguments: \n\(args)\n\n"
print(msgAsString)
oscLogView.string?.append(msgAsString)
oscLogView.scrollToEndOfDocument(self)
}
Как вы можете видеть здесь (это функция обратного вызова), я обновляю TextView непосредственно из обратного вызова (как добавляя данные, так и прокручивая до конца) каждый раз, когда получено сообщение. Именно здесь Инструменты говорят мне, что происходит замедление, и добавление является самым медленным. Я не пошел дальше этого в анализе, но это, безусловно, связано с тем, что он пытается сделать визуальное обновление, которое занимает намного больше времени, чем разбор 32-битных данных, и когда он закончен, он получает еще одно обновление прямо подальше от буфера сервера.
Могу ли я отправить этот вызов в фоновый поток? Мне не кажется хорошей идеей заполнять фоновую ветку визуальными обновлениями. Может быть, увеличить свой собственный строковый буфер и время от времени сбрасывать его в TextView с помощью таймера?
Я хочу придать этому ощущение консоли, но консоль, которая зависает, — это не консоль.
Вот ссылка на проект на github. все стручки уже есть и настроены с помощью кокоаподов, так что просто откройте рабочее пространство. У вас, ребята, может не быть ничего, чтобы генерировать столько OSC-трафика, но если вы действительно хотите покопаться, вы можете получить IanniX, который представляет собой секвенсор/автомат траектории с открытым исходным кодом, который может генерировать OSC и многое другое. Я только что скачал его, и я создам быстрый проект, который должен отправить достаточно данных, чтобы заморозить приложение, и я добавлю его в репозиторий, если кто-то захочет попробовать.