Избегайте блокировки основного потока в NSDraggingSession с использованием NSPasteboardItemDataProvider
В приложении Mac OS X (Какао) я копирую некоторые изображения из моего приложения в другие, используя NSDraggingSession
, NSDraggingItem
использует объект, который реализует протокол NSPasteboardItemDataProvider
, чтобы предоставить данные, когда пользователь удаляет их.
Поскольку я имею дело с изображениями, используются следующие типы: NSPasteboardTypePNG
, kPasteboardTypeFileURLPromise
, kUTTypeFileURL
, com.adobe.photoshop-image
а также public.svg-image
, Эти изображения находятся в удаленном месте, поэтому, прежде чем я смогу предоставить их на монтажную панель, я должен загрузить их из Интернета.
Я реализую метод - pasteboard(pasteboard:item:provideDataForType:)
делать что-то вроде этого:
Если запрашиваемый тип
kPasteboardTypeFileURLPromise
Я получаю место вставки, собираю и задаю в монтажной доске строку URL с тем местом, где файл должен быть записан в будущем.Если запрашиваемый тип
kUTTypeFileURL
Я загружаю файл, указываю временное местоположение и записываю загруженный файл в это место. Затем я установил в монтажной доске строку URL-адреса местоположения.Если запрашиваемый тип является одним из других, я загружаю файл и устанавливаю простой
NSData
в картоне.
Все эти операции выполняются в главном потоке, создавая некоторые лаги, от которых я хочу избавиться.
Я попытался выполнить эти операции в фоновом потоке и вернулся к основному потоку, чтобы установить окончательные данные в монтажном столе, но это не работает, потому что метод завершается раньше.
Кто-нибудь знает способ добиться этого?
1 ответ
Обещания типов картона обычно подразумевают альтернативный формат данных, который у вас уже есть, когда вы хотите избежать затрат времени и памяти на конвертацию до того, как это потребуется. Я не думаю, что действительно целесообразно использовать его для отсрочки загрузки каких-либо данных. Во-первых, загрузка может завершиться неудачно, когда она в конечном итоге будет запрошена. С другой стороны, это может занять произвольно много времени, как вы боретесь сейчас.
Итак, я думаю, что вы должны загрузить данные заранее. Либо сохраните его в памяти, либо сохраните во временный файл. Используйте обещанные типы, если это уместно, чтобы доставить его в разных формах, но имейте его под рукой заранее.