在主线程上运行closures

我创build了一个类,比开发人员更容易实现select器视图。 在UIPickerView数据源方法中,我从闭包中返回值。 例:

func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { return pickerNumberOfRows!(component: component) } 

我对所有的数据源方法使用相同的东西。 当我运行应用程序,它显示屏幕上的select器没有数据。 问题是我从闭包接收数据,而这些闭包在主线程上没有运行。

有没有办法在主线程上运行该闭包,并确保它返回一个适合数据源函数返回值types的值? (例如,从上面的例子来看,闭包将返回一个Int)

编辑:

我知道使用dispatch_async。 但是,在我的情况下,它不会帮助我。 假设我创build了一个在主线程上运行闭包的函数,并且需要返回值如下所示:

 func closureOnMainThread()->Int{ dispatch_async(dispatch_get_main_queue()) { // Run your code here return self.pickerNumberOfRows!(component: 0) } return 0 } 

但是,在返callback度块内部的值之前,返回0的函数存在一个问题。

编辑2:弄清楚事情。 我的代码包含一个自定义类的select器和一个UIViewController实现它:

 class CustomPickerView: NSObject, UIPickerViewDelegate, UIPickerViewDataSource { var pickerNumberOfRows: ((component: Int)->Int)? //MARK: UIPickerViewDatasource Methods func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { return pickerNumberOfRows!(component: component) } func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int { return pickerNumberOfComponents!() } func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {print("Hello") return pickerRowTitle!(forRow: row, inComponent: component) } //MARK: UIPickerViewDelegate Methods func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { pickerDidSelect!(row: row, component: component) } } 

UIViewController(视图加载):

 override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. let picker = CustomPickerView(parent: self) picker.pickerNumberOfRows = { component in return 10 } } 

请注意,我删除了之间的配件function的分配,以便您专注于主代码部分。

开发人员可以在closures的variables中传递他想要的逻辑。

希望我现在不能忍受。 在这个模块中,你可以运行任何代码,它将在主线程上执行。

 dispatch_async(dispatch_get_main_queue()) { // Run your code here } 

你可以运行这个知道你是否在主线程中:

 NSThread.isMainThread() 

编辑

你正在寻找的是,返回一个同步响应insted: – >诠释

你应该返回一个块,asynchronous响应:

 func someLongProcessTaskAndReturnCompenents(completion: (components: Int)->Void){ //Here you can do your long process task on back thread... dispatch_async(dispatch_get_main_queue()) { completion(self.pickerNumberOfRows!(component: 0)) } } 

现在,当你运行它时,响应将会返回同步:

 someLongProcessTaskAndReturnCompenents { (components) in //Your logic after response } 

你不能把dispatch_async放在closureOnMainThread中。 这是一个asynchronous过程,所以它将返回在GCD块之外定义的0。 所以在closures代码里面肯定有一些问题。

它必须同步而不是asynchronous的。

所以试试这样的一些。 – 这只是一个示例代码块。 假设pickerNumberOfRows将在同一个线程上返回一个Int(我使用dispatch_sync而不是dispatch_async

 func closureOnMainThread()->Int{ var x = 0; if (NSThread.isMainThread() == true) { x = self.pickerNumberOfRows!(component: 0) } else { dispatch_sync(dispatch_get_main_queue()) { x = self.pickerNumberOfRows!(component: 0) } } return x } 

好的,这个问题甚至不涉及线程/closures。 问题是在视图控制器中使用letvar实例化自定义select器。 这是一个新的视图控制器实现:

 var picker: HBPickerView? override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. picker = HBPickerView(parent: self) picker!.presentPicker() } 

感谢所有分享他们答案的人。