Swift - 使用performSelectorOnMainThread

时间:2016-05-16 06:52:36

标签: swift cocoa background-process

我正在尝试将– performSelectorOnMainThread:withObject:waitUntilDone:用于我在Swift中开发的Cocoa应用程序。我需要应用程序等待工作完成。无论如何,我有以下几行代码。

func recoverData(path:String) -> Void {
    let sheetRect:NSRect = NSMakeRect(0,0,400,114)
    let progSheet:NSWindow = NSWindow.init(contentRect:sheetRect, styleMask:NSTitledWindowMask,backing:NSBackingStoreType.Buffered,`defer`:true)
    let contentView:NSView = NSView.init(frame:sheetRect)
    let progInd:NSProgressIndicator = NSProgressIndicator.init(frame:NSMakeRect(190,74,20,20))
    progInd.style = NSProgressIndicatorStyle.SpinningStyle
    let msgLabel:NSTextField = NSTextField.init(frame:NSMakeRect(20,20,240,46))
    msgLabel.stringValue = "Copying selected file..."
    msgLabel.bezeled = false
    msgLabel.drawsBackground = false
    msgLabel.editable = false
    msgLabel.selectable = false
    contentView.addSubview(msgLabel)
    contentView.addSubview(progInd)
    progSheet.contentView = contentView

    self.window.beginSheet(progSheet) {(NSModalResponse returnCode) -> Void in
        progSheet.makeKeyAndOrderFront(self)
        progInd.startAnimation(self)
        let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
        dispatch_async(dispatch_get_global_queue(priority,0)) {

            //////////////////////////////////////////////////////////////////////////////////////////////////
            self.performSelectorOnMainThread(Selector(self.readData(path)),withObject:path,waitUntilDone:true)
            //////////////////////////////////////////////////////////////////////////////////////////////////

        }

        dispatch_async(dispatch_get_main_queue()) {
            progInd.indeterminate = true
            self.window.endSheet(progSheet)
            progSheet.orderOut(self)
        }
    }
}

func readData(path:String) -> Void {
    print("Hello!?")
}

我不确定如何将path传递给readData。 Xcode要求我将参数设置为除nil之外的其他内容。在Objective-C中,它将是

[self performSelectorOnMainThread:@selector(readData:) withObject:path waitUntilDone:YES];

无论如何,应用程序永远不会到达readData。我做错了什么?

感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

为什么不

self.window.beginSheet(progSheet) {(returnCode) -> Void in
    dispatch_async(dispatch_get_main_queue()) {
        progInd.startAnimation(self)
        self.readData(path)
        progInd.indeterminate = true
    }
}

在某些时候你必须致电self.window.endSheet(progSheet)来解雇工作表并调用完成处理程序。

修改

我猜你实际上是指这样的事情

...
  self.window.beginSheet(progSheet) {(returnCode) -> Void in
    progInd.stopAnimation(self)
    progInd.indeterminate = true

  }

  progInd.startAnimation(self)
  let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
  dispatch_async(dispatch_get_global_queue(priority,0)) {
    self.readData(path) {
      dispatch_async(dispatch_get_main_queue()) {
        self.window.endSheet(progSheet)
      }
    }
  }
}

func readData(path:String, completion: (()  -> Void))  {
  print("Hello!?")
  completion()
}