如何从 dispatch_sync(dispatch_get_main_queue(), 发送/返回值到另一个页面

Posted

技术标签:

【中文标题】如何从 dispatch_sync(dispatch_get_main_queue(), 发送/返回值到另一个页面【英文标题】:How to sent / return values from dispatch_sync(dispatch_get_main_queue(), to another page如何从 dispatch_sync(dispatch_get_main_queue(), 发送/返回值到另一个页面 【发布时间】:2016-12-08 09:19:12 【问题描述】:

我创建了一个项目,它将检索提取的 JSON 数据并将其显示在 UITableview 中。我不想通过下载所有内容来增加应用程序的负担。因此,只有当用户选择一行时,它才会检索员工详细信息。我正在使用页面视图控制器,以便用户能够通过滑动页面来导航每个页面。 如何将我在 dispatch_sync 中为页面发送的值发送到 detailviewcontroller 页面?

这是我来自 managePageviewController 的代码

func viewDetailViewController(index: Int) -> DetailViewController? 
    if let storyboard = storyboard,
        page = storyboard.instantiateViewControllerWithIdentifier("DetailViewController") as? DetailViewController         

                let currentEmployee = employeeStore.searchEmployee[index]

                getJson().testsearchJSON(currentEmployee.id, handler: (employeeDetails) -> Void in
                    dispatch_sync(dispatch_get_main_queue(), 
                        page.employee = employeeDetails
                        page.employeeIndex = index
                        return page //fail here
                    )
                )
    
    return nil

这是我的 getJSON().testSearchJSON 基金

func testsearchJSON(id:String, handler: (Employee) -> Void) 
    let requestURL: NSURL = NSURL(string: (favUrl + id))!
    let urlRequest: NSMutableURLRequest = NSMutableURLRequest(URL: requestURL)
    let session = NSURLSession.sharedSession()
    let task = session.dataTaskWithRequest(urlRequest) 
        (data, response, error) -> Void in

        let httpResponse = response as! NSHTTPURLResponse
        let statusCode = httpResponse.statusCode

        //retrieve data successfully
        if (statusCode == 200) 
            do 
                let json = try NSJSONSerialization.JSONObjectWithData(data!, options: .AllowFragments)
                if data!.length > 0 && error == nil 

                    guard let name = json["firstName"] as? String,
                    let title = json["title"] as? String,
                    let id = json["id"]!,
                    let manager = json["managerName"] as? String,
                    let oa = json["oa"] as? String,
                    let email = json["email"] as? String,
                    let department = json["department"] as? String,
                    let division = json["division"] as? String,
                    let company = json["company"] as? String
                    else 
                            return;
                    
                    let newEmployee = Employee(id: String(id), name: name, title: title, manager: manager, oa: oa, email: email, department: department, division: division, company: company)

                    //test

                    handler(newEmployee)

                
             catch 
                print("Error with JSON: \(error)")
            
        
    
    task.resume()
  

这是我的 DetailviewController 页面

class DetailViewController: UIViewController, UITextFieldDelegate 

// MARK:- Propertise
@IBOutlet var employeePic: UIImageView! //employee picture
@IBOutlet var employeeName: UILabel! // name
@IBOutlet var employeeTitle: UILabel! //job title
@IBOutlet var dateCreated: UILabel!
@IBOutlet var managerName: UITextField!
@IBOutlet var oaName: UITextField!
@IBOutlet var emailField: UITextField!
@IBOutlet var departmentField: UITextField!
@IBOutlet var divisionField: UITextField!
@IBOutlet var companyField: UITextField!


var employee: Employee! 
    //add applicataion name
    didSet 
        navigationItem.title = employee.name
    

//current employee index
var employeeIndex: Int!

let dateFormatter: NSDateFormatter = 
    let formatter = NSDateFormatter()
    formatter.dateStyle = .MediumStyle
    formatter.timeStyle = .NoStyle
    return formatter
()

//MARK:- assign values
override func viewWillAppear(animated: Bool) 
    super.viewWillAppear(animated)

    employeeName.text = employee.name
    employeeTitle.text = "( " + employee.title + " )"
    emailField.text = employee.email
    managerName.text = employee.manager
    dateCreated.text = dateFormatter.stringFromDate(employee.dateCreated)
    oaName.text = employee.oa
    departmentField.text = employee.department
    divisionField.text = employee.division
    companyField.text = employee.company

    //retrieve image
    employeePic.thumbnails()
    employeePic.image = UIImage(named: "Default Image")


【问题讨论】:

【参考方案1】:

我认为在这种情况下,最好在 DetailViewController 中的 viewDidLoad 或 viewWillAppear 函数中编写数据获取。类似的东西:

在 MainViewController 中:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
    viewDetailViewController(index : indexPath.row, employee: employeeStore.searchEmployee[indexPath.row])


func viewDetailViewController(index: Int, employee: Employee) 
    let detailController = storyboard.instantiateViewControllerWithIdentifier("DetailViewController") as? DetailViewController 
    detailController.currentEmployee = employee
    // present/push/etc detail controller
    present(detailViewController, animated: true, completion: nil)

在 DetailViewController 中:

var employee : Employee?
...

override func viewDidLoad() 
    super.viewDidLoad()
    if let employee = currentEmployee 
        getJson().testsearchJSON(employee.id, handler: (employeeDetails) -> Void in
                dispatch_sync(dispatch_get_main_queue(), 
                    //reload UI for employeeDetails
             )
        )
    

您也可以使用 GCD 等待块加载,例如 GCD 组。

【讨论】:

感谢您的帮助。我正在使用 managePageViewController... 是否可以在不通过 segue 的情况下浏览页面? 不客气 :) 是的,这是可能的。对于 UIPageViewController,我发现这个要点可能会有所帮助 - gist.github.com/andreif/3bace9961c7e70995856。你也可以通过***搜索:)【参考方案2】:

试着喜欢这个

func viewDetailViewController(index: Int) -> DetailViewController? 
    if let storyboard = storyboard,
        page = storyboard.instantiateViewControllerWithIdentifier("DetailViewController") as? DetailViewController         

                let currentEmployee = employeeStore.searchEmployee[index]

                getJson().testsearchJSON(currentEmployee.id, handler: (employeeDetails) -> Void in
                        page.employee = employeeDetails
                        page.employeeIndex = index
                        return page //fail here
                )
    
    return nil


func testsearchJSON(id:String, handler: (Employee) -> Void) 
    let requestURL: NSURL = NSURL(string: (favUrl + id))!
    let urlRequest: NSMutableURLRequest = NSMutableURLRequest(URL: requestURL)

    let semaphore = dispatch_semaphore_create(0);

    let session = NSURLSession.sharedSession()
    let task = session.dataTaskWithRequest(urlRequest) 
        (data, response, error) -> Void in

        let httpResponse = response as! NSHTTPURLResponse
        let statusCode = httpResponse.statusCode

        //retrieve data successfully
        if (statusCode == 200) 
            do 
                let json = try NSJSONSerialization.JSONObjectWithData(data!, options: .AllowFragments)
                if data!.length > 0 && error == nil 

                    guard let name = json["firstName"] as? String,
                    let title = json["title"] as? String,
                    let id = json["id"]!,
                    let manager = json["managerName"] as? String,
                    let oa = json["oa"] as? String,
                    let email = json["email"] as? String,
                    let department = json["department"] as? String,
                    let division = json["division"] as? String,
                    let company = json["company"] as? String
                    else 
                            dispatch_semaphore_signal(semaphore);
                            return;
                    
                    let newEmployee = Employee(id: String(id), name: name, title: title, manager: manager, oa: oa, email: email, department: department, division: division, company: company)

                    //test

                    handler(newEmployee)
                    dispatch_semaphore_signal(semaphore);
                
             catch 
                dispatch_semaphore_signal(semaphore);
                print("Error with JSON: \(error)")
            
        
    
    task.resume()
    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)
  

【讨论】:

GDC返回页面部分失败。 你能换行吗 handler(newEmployee) dispatch_semaphore_signal(semaphore);

以上是关于如何从 dispatch_sync(dispatch_get_main_queue(), 发送/返回值到另一个页面的主要内容,如果未能解决你的问题,请参考以下文章

我该如何解决:使用纱线工作区在 React Native 中“加载 RCTBridge 需要 dispatch_sync 加载”?

如何在 Swift 3、Swift 4 及更高版本中 dispatch_sync、dispatch_async、dispatch_after 等?

dispatch_sync()

dispatch_sync和dispatch_async的区别

dispatch_sync

为啥我们不能在当前队列上使用 dispatch_sync?