2016-06-02 2 views
1

Я новичок в Swift (2.2), и у меня возникла проблема с простым приложением, использующим Xcode 7.3 и OS X 10.11. В этом приложении пользователь нажимает кнопку и выбирает файл через NSOpenPanel. Код использует URL-адрес, выбранный для получения данных и имени файла, затем обрабатывает данные и сохраняет результат в другом месте. С большими файлами обработка может занять несколько секунд. При обработке больших файлов после выбора файла пространство, в котором было открыто окно Open File, остается пустым, охватывая вид приложения и все остальное, и остается там до завершения операции. Кроме того, розетки приложений заморожены до завершения операции. Похоже, NSOpenPanel не передает управление окном в приложение и систему.NSOpenPanel не будет корректно закрываться во время функции Swift

код выглядит следующим образом:

@IBAction func processFile(sender: AnyObject) { 
    var chosenURL: NSURL? 
    let openPanel = NSOpenPanel() 
    openPanel.title = "Choose a file" 
    openPanel.canChooseDirectories = false 
    openPanel.allowsMultipleSelection = false 

    if openPanel.runModal() == NSFileHandlingPanelOKButton { 
      chosenURL = openPanel.URL 
    } 
    let dataBytes = NSData(contentsOfURL: chosenURL!) 
    let fileName = chosenURL!.lastPathCompnent! 
    // Remaining code processes dataBytes and fileName 

Я пробовал несколько вариантов, но получить тот же результат. Поиск «NSOpenPanel не закрывается» в сети, как правило, просто приводит примеры в Objective-C, о которых я ничего не знаю. Любые предложения о том, как заставить NSOpenPanel отключиться и просмотреть и управлять, вернутся в окно приложения?

+0

'NSData (contentsOfURL: selectedURL!)' Это то, что блокирует ваш пользовательский интерфейс. Вы должны получить данные в фоновом режиме. – Moritz

+0

Я не уверен, что это значит. Это связано с GCD? – Micos

ответ

1

Следуя предложению Эрика Д, я заглянул в Grand Central Dispatch и фоновые процессы. Мой первый подход:

dispatch_async(dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0)) { 
dataBytes = NSData(contentsOfURL: chosenURL!) 
} 

Это ничего не меняет. Я обнаружил, что мне пришлось отложить весь оставшийся процесс (все, начиная с «let dataBytes ...» и далее) в рамках закрытия отправки, с операциями dispatch_async (dispatch_get_main_queue()) вокруг обновлений пользовательского интерфейса. Это остановило окно от замораживания и гашения и вернуло управление в приложение. Еще раз спасибо, Эрик.

Смежные вопросы