简体   繁体   中英

Swift queues syntax

I'm writing a program that retrieves values from a database and displays it on the UI. The retrieval step executes asynchronously and as a result the result box gets updated before the db results come back. Right now I can get it to work by using a NSThread.sleepForTimeInterval(time) above the "ResultBox.text = globaldbresults" but I know that is a bad way to do it since the retrieval time will vary depending on the size of the retrieval etc. I much prefer to ensure a block (the UI textfield update) only runs after the retrieve has completed.

I've tried using dispatch_group_wait but I think I'm using it wrong.

[In AppDelegate.swift]
var globaldbresults
@UIApplicationMain
[END In Appdelegate.swift]

import UIKit
import Dispatch

class ViewController: UIViewController { 
  dbGetqueue = dispatch_group_create()
  @IBAction func goClicked(sender: AnyObject) {

    dispatch_group_enter(dbGetqueue)
    mysqlget(Room1num, num2: Room2num)
    dispatch_group_leave(dbGetqueue)

    dispatch_group_wait(dbGetqueue, 5)
    ResultBox.text = globaldbresults
  } 

  func mysqlget(num1 :Int, num2 :Int) { 
    let myUrl = NSURL(string: "http://localhost/iOS_PHP_MySQL.php")
    let myGetTask = NSURLSession.sharedSession().dataTaskWithRequest(myRequest, completionHandler: {(reqData, reqResponse, reqError) -> Void in 
      dbresults = (NSString(data: reqData, encoding: NSUTF8StringEncoding)!) 
      globaldbresults = String(dbresults) 
    }) 
    myGetTask.resume() 
  } 
}

I've just put the relevant lines of code. The globaldbresults which is bad way to deal with one of my problem solves the scope issue which occurs if I try to directly reference dbresults from my goClicked Action.

I would it should be:

dispatch_group(dbGetqueue) {
  block to execute
}

[Some other code not dependent on block above]

dispatch_group_wait(dbGetqueue) {
  code that doesn't start till dbGetqueue finished
}

but that is obviously not the case.

If you have only one request to get desired data this could be solved by a simple callback closure.

But if you want to do it with dispatch_group_ way here it could be done:

class ViewController: UIViewController { 
   dbGetqueue = dispatch_group_create()
   @IBAction func goClicked(sender: AnyObject) {

   mysqlget(Room1num, num2: Room2num)

   dispatch_group_notify(dbGetqueue,dispatch_get_main_queue(),{
       self.ResultBox.text = globaldbresults     
   })

} 

func mysqlget(num1 :Int, num2 :Int) {
    dispatch_group_enter(dbGetqueue) //Enter group here
    let myUrl = NSURL(string: "http://localhost/iOS_PHP_MySQL.php")

    let myGetTask = NSURLSession.sharedSession().dataTaskWithRequest(myRequest, completionHandler: {(reqData, reqResponse, reqError) -> Void in 

        dbresults = (NSString(data: reqData, encoding: NSUTF8StringEncoding)!) 
        globaldbresults = String(dbresults)
        dispatch_group_leave(self.dbGetqueue) //Leave group when you are done getting results.

    }) 
    myGetTask.resume() 
  } 

Another way of doing without dispatch_group_ is

class ViewController: UIViewController { 
   dbGetqueue = dispatch_group_create()
   @IBAction func goClicked(sender: AnyObject) {

   mysqlget(Room1num, num2: Room2num)

   } 

func mysqlget(num1 :Int, num2 :Int) {

    let myUrl = NSURL(string: "http://localhost/iOS_PHP_MySQL.php")

    let myGetTask = NSURLSession.sharedSession().dataTaskWithRequest(myRequest, completionHandler: {(reqData, reqResponse, reqError) -> Void in 

        dbresults = (NSString(data: reqData, encoding: NSUTF8StringEncoding)!) 
        globaldbresults = String(dbresults)
        dispatch_async(dispatch_get_main_queue(), {
        self.self.ResultBox.text = globaldbresults
    })


    }) 
    myGetTask.resume() 
  } 
}


}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM