我正在尝试使用自定义tableview单元格加载tableview。
这是我的tableview控制器的viewDidLoad()
看起来的样子:
override func viewDidLoad(){
super.viewDidLoad()
self.tableView?.delegate = self;
self.tableView?.dataSource = self;
//Clean array data
TableData.removeAll()
//Retrieve data asynchronously
let call = webApi()
call.retrieveAllShops()
doTableRefresh()
}
TableData是一个全局数组,我将所有json数据放入其中。
所以我先把它清理干净再填充它。
我填写call.retrieveAllShops()
private func retrieveAllShops(){
let request = NSMutableURLRequest(URL: NSURL(string: userApiCallUrl)!)
request.HTTPMethod = "POST"
request.HTTPBody = postParam.dataUsingEncoding(NSUTF8StringEncoding)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in
guard error == nil && data != nil else {
// check for fundamental networking error
print("error=\(error)")
return
}
if let httpStatus = response as? NSHTTPURLResponse where httpStatus.statusCode != 200 {
// check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(response)")
}
let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
let json: AnyObject? = responseString!.parseJSONString
self.parseJson((json as! NSMutableArray))
}
task.resume()
}
最后在parseJson()
中填写全局数组TableData:
private func parseJson(json : NSMutableArray){
for j in json {
//Create main value
guard let value = j.valueForKey("value")?.valueForKey("value")! else{
continue
}
//Get name
guard let Name : String = (value.valueForKey("Name")?.valueForKey("en") as? String) else {
continue
}
TableData.append(Name)
}
}
然后回到tableView控制器,我调用doTableRefresh()
private func doTableRefresh(){
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.tableView.reloadData()
return
})
}
最后我有这两种方法。
func tableView(tableView:UITableView, numberOfRowsInSection section:Int) -> Int
{
if(searchActive) {
return filtered.count
}
return TableData.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell : shopsTableViewCell = tableView.dequeueReusableCellWithIdentifier("shopCell", forIndexPath: indexPath) as! shopsTableViewCell
if(searchActive){
cell.textLabel?.text = filtered[indexPath.row]
} else {
cell.textLabel?.text = TableData[indexPath.row]
}
cell.shopTitle = TableData[indexPath.row]
return cell
}
现在如果我在方法return TableData.count
的{{1}}行中设置断点,它总是在异步调用加载全局数组之前首先进入此处,因此它返回0并且我的tableview单元格根本不显示。
有人可以告诉我,我做错了吗?
编辑:
在我的tableView(tableView:UITableView, numberOfRowsInSection section:Int)
方法中做了一些更改之后:
viewDidLoad
在我的 override func viewDidLoad(){
super.viewDidLoad()
self.tableView?.delegate = self;
self.tableView?.dataSource = self;
//Clean array data
TableData.removeAll()
//Retrieve data asynchronously
let call = webApi()
call.retrieveAllShops({
data in
self.doTableRefresh()
})
}
方法中:
func retrieveAllShops(success:SuccessClosure){ setGetShopsListUrl()
retrieveAllShops()
}
我的应用程序崩溃了:
这是我收到的错误消息:
call()
success(data: "sucess")
可能看起来没有连接插座所以,我删除了旧连接并做了一个新连接,但结果相同(旧连接没问题):
答案 0 :(得分:0)
在json解析后调用doTableRefresh
let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
let json: AnyObject? = responseString!.parseJSONString
self.parseJson((json as! NSMutableArray))
self.doTableRefresh()
...
被修改
//全局创建
public typealias SuccessClosure = (data: String?) -> (Void)
并在您的班级中调用call.retrieveAllShops() 将SuccessClosure作为参数传递
call.retrieveAllShops({
data in
self.doTableRefresh()
// refresh tableview here
})
和retrieveAllShops方法
private func retrieveAllShops(success: SuccessClosure) {
...
self.parseJson((json as! NSMutableArray))
success("sucess") // you can pass data according to your requirment here
}
答案 1 :(得分:0)
你没有做错任何事。这就是异步网络的本质。
您唯一认为缺少的是,在retrieveAllStops()
方法的完成时段结束时,您需要添加对doTableRefresh()
的通话(正好在self.parseJason()
的调用下
在viewDidLoad中调用doTableRefresh()
没有任何帮助,所以你也可以删除该调用。 (表视图数组数据尚不可用。)
如果在另一个类中定义了表视图,则添加方法dataIsAvailable并调用它。 (或者@SahilBeri说,在retrieveAllStops()
方法中添加一个闭包,并在下载和解析数据后调用闭包。)
如果您决定调用dataIsAvailable方法,那么您可能希望将一个委托添加到JSON提取类,并将dataIsAvailable()
方法作为委托方法。