Swift PHP发布请求从任务中设置全局变量
Posted
技术标签:
【中文标题】Swift PHP发布请求从任务中设置全局变量【英文标题】:Swift PHP post request set global variable from task 【发布时间】:2016-06-29 02:16:17 【问题描述】:我使用发布请求成功地从数据库中检索数据。 (我不想使用get request,因为我想向php发送验证。)不要担心php部分,应该没问题。
import UIKit
class mainPage: UIViewController, UITableViewDelegate, UITableViewDataSource
@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var toolBar: UIToolbar!
var values:NSArray = []
@IBOutlet weak var Open: UIBarButtonItem!
override func viewDidLoad()
super.viewDidLoad()
Open.target = self.revealViewController()
Open.action = #selector(SWRevealViewController.revealToggle(_:))
self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
get()
func get()
let request = NSMutableURLRequest(URL: NSURL(string: "http://www.percyteng.com/orbit/getAllpostsTest.php")!)
request.HTTPMethod = "POST"
let postString = "user=\("ios")"
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request)
data, response, error in
if error != nil
print("error=\(error)")
return
print("response = \(response)")
let array = try! NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as! NSArray
self.values = array
task.resume()
dispatch_async(dispatch_get_main_queue()) tableView.reloadData()
override func didReceiveMemoryWarning()
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
func numberOfSectionsInTableView(tableView: UITableView) -> Int
return 1
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
if values.count > 20
return 20
else
return values.count
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as!postCell
let maindata = values[values.count-1-indexPath.row]
if maindata["category"] as? String == "Services"
cell.postImg.image = UIImage(named: "tile_services")
else if maindata["category"] as? String == "exchange"
cell.postImg.image = UIImage(named: "tile_exchange")
else if maindata["category"] as? String == "Tutors"
cell.postImg.image = UIImage(named: "tile_tutoring")
else if maindata["category"] as? String == "Sports"
cell.postImg.image = UIImage(named: "tile_sports")
else if maindata["category"] as? String == "Sublet"
cell.postImg.image = UIImage(named: "tile_sublet")
else if maindata["category"] as? String == "Events"
cell.postImg.image = UIImage(named: "tile_events")
else
cell.postImg.image = UIImage(named: "tile_carpool")
if maindata["category"] as? String == "Services" || maindata["category"] as? String == "Tutors" || maindata["category"] as? String == "Events"
cell.title.text = maindata["title"] as? String
else if maindata["category"] as? String == "Sublet" || maindata["category"] as? String == "Rideshare"
cell.title.text = maindata["location"] as? String
else
cell.title.text = maindata["item"] as? String
if maindata["category"] as? String == "Sublet" || maindata["category"] as? String == "Rideshare"
cell.location.text = ""
else
cell.location.text = maindata["location"] as? String
cell.category.text = maindata["category"] as? String
cell.price.text = maindata["price"] as? String
return cell
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
所以我有一个名为 values 的全局变量,它是一个 NSArray,我想将此数组的值设置为我从数据库中检索的数组。但是,在函数 get() 中,发布请求充当另一个线程,我必须编写 self.values = array 这不会改变我的全局变量的值。
我需要该值来在主数组中组织我的 tableview。
基本上,我的问题是如何从闭包中获取值并将其设置为全局变量。
谢谢!如果你们不明白我在说什么,请告诉我。
【问题讨论】:
使用调试器在self.values = array
处添加断点,并检查array
在该位置停止时的值(在左下视图或在控制台中键入p dump(array)
) .另外我建议使用[AnyObject]
而不是NSArray
。
嘿,我在之前和那时检查过,数组提供了我想要从数据库中获取的正确信息。在任务关闭之外没有任何东西被保存
【参考方案1】:
您需要在 func get()
中添加一个完成处理程序,因为您正在执行 dataTaskWithRequest
这是一个 Async
调用。试试这个:
func get(finished: (isDone: Bool) -> ())
//your code
data, response, error in
if error != nil
finished(isDone: false)
print("error=\(error)")
return
print("response = \(response)")
let array = try! NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as! NSArray
self.values = array
task.resume()
finished(isDone: true)
然后在你的viewDidLoad
:
override func viewDidLoad()
super.viewDidLoad()
get success in
if success
//reload your tableview here
【讨论】:
这是一个不错的答案,但其他人为我提供了一个完成处理程序来传递数据,而不仅仅是一个布尔变量。谢谢!【参考方案2】:闭包隐式地保留了 self,所以你实际上是在修改那个属性。但是在闭包中检索到数据后,您需要使用reloadCellsAtIndexPath
、insertCellsAtIndexPath
或reloadData
刷新您的tableView。后者是最简单的方法,但完全替代了表的当前状态。
此外,您在闭包中导致了一个保留周期。您应该将 self 作为 weak
或 unowned
属性传递,以让 ARC 完成其工作。欲了解更多信息:http://krakendev.io/blog/weak-and-unowned-references-in-swift
例子:
func get()
let request = NSMutableURLRequest(URL: NSURL(string: "http://www.percyteng.com/orbit/getAllpostsTest.php")!)
request.HTTPMethod = "POST"
let postString = "user=\("ios")"
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request)
data, response, error in
if error != nil
print("error=\(error)")
return
print("response = \(response)")
let array = try! NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as! NSArray
self.values = array
dispatch_async(dispatch_get_main_queue()) [unowned self] in
self.tableView?.reloadData();
task.resume()
【讨论】:
我刚刚编辑了我的代码,在我执行 task.resume() 之后我确实有 tableview.reloadData。这并没有真正做任何事情。 @PercyTeng 因为数据是异步传递的,所以当你用resume
发送请求后立即刷新它不会发生任何事情。实际分配数组时需要刷新它。
问题是,我正在将数据从数据库检索到任务线程中的变量数组,但我想先将其设置为全局变量“values”,并且我的 tableview 的值将根据“价值观”的价值。所以赋值数组的代码在那个线程中,但是给tableview赋值的代码在另一个线程中
我知道你的意思,我应该在为变量赋值后重新加载 tableview 数据,因为所有 tableview 数据都是从变量“values”加载的,但我的问题是我的代码从不为变量“values”,因为“values”是主线程中的全局变量,而我在另一个线程中获取我想要的数据,即发布请求
其他线程无所谓,self仍然被捕获在闭包内。设置 values 属性后,您不会在闭包中重新加载数据。您需要在闭包内设置 self.value 后立即执行此操作。您可以使用 `dispatch_async(dispatch_get_main_queue(), [unowned self] in ) 在主线程上执行它以上是关于Swift PHP发布请求从任务中设置全局变量的主要内容,如果未能解决你的问题,请参考以下文章