如何从 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 等?