伙计们,我从FoursquareAPI获取数据,下面是我的代码。
但是我在cellForRowAtIndexPath得到了一个零错误venueItems是零
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
// Table View
self.tableView = UITableView()
// Location Manager Stuff
self.locationManager = CLLocationManager()
self.locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
self.locationManager.delegate = self
let status = CLLocationManager.authorizationStatus()
if status == .notDetermined {
self.locationManager.requestWhenInUseAuthorization()
} else if status == CLAuthorizationStatus.authorizedWhenInUse
|| status == CLAuthorizationStatus.authorizedAlways {
self.locationManager.startUpdatingLocation()
} else {
showNoPermissionsAlert()
}
exploreVenues()
}
// Func's
func exploreVenues() {
guard let location = self.locationManager.location else {
return
}
var parameters = [Parameter.query: "Pubs"]
parameters += location.parameters()
let task = self.session.venues.explore(parameters) {
(result) -> Void in
if self.venueItems != nil {
return
}
if !Thread.isMainThread {
fatalError("!!!")
}
if let response = result.response {
if let groups = response["groups"] as? [[String: AnyObject]] {
var venues = [[String: AnyObject]]()
for group in groups {
if let items = group["items"] as? [[String: AnyObject]] {
venues += items
}
}
self.venueItems = venues
}
self.tableView.reloadData()
} else if let error = result.error, !result.isCancelled() {
self.showErrorAlert(error)
}
}
task.start()
}
// Table View Data source
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if let venueItems = self.venueItems {
return venueItems.count
}
return 10
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! VenueTableViewCell
// This is where the error occurs
let item = self.venueItems![(indexPath as NSIndexPath).row] as JSONParameters!
self.configureCellWithItem(cell, item: item!)
return cell
}
func configureCellWithItem(_ cell: VenueTableViewCell, item: JSONParameters) {
if let venueInfo = item["venue"] as? JSONParameters {
cell.nameLabel.text = venueInfo["name"] as? String
}
}
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
let cell = cell as! VenueTableViewCell
let tips = self.venueItems![(indexPath as NSIndexPath).row]["tips"] as? [JSONParameters]
guard let tip = tips?.first, let user = tip["user"] as? JSONParameters,
let photo = user["photo"] as? JSONParameters else {
return
}
let URL = photoURLFromJSONObject(photo)
if let imageData = session.cachedImageDataForURL(URL) {
cell.venueImageView.image = UIImage(data: imageData)
} else {
cell.venueImageView.image = nil
session.downloadImageAtURL(URL) { (imageData, error) -> Void in
let cell = tableView.cellForRow(at: indexPath) as? VenueTableViewCell
if let cell = cell, let imageData = imageData {
let image = UIImage(data: imageData)
cell.venueImageView.image = image
}
}
}
}
}
我个人对编程很陌生,我认为venueItems是零的,因为
cellForRowAtIndexPath
是先执行的。如果这是一个错误,我如何修复它,使cellForRowAtIndexpath中的代码在我的venueItems有值之后运行。。或者其他更有效的方法? 最佳答案
当numberOfRowsInSection
为零时,10
返回self.venueItems
。self.venueItems
在您的网络请求完成之前似乎为nil,因此在被告知表视图有10行要显示时,表视图会为每行请求一个单元格。然后尝试强制展开可选属性(self.venueItems!
)并崩溃。
看起来您的self.venueItems
是可选的,原因很好,不要使用强制展开(!
)来丢弃该信息。当这个属性为nil时,您可以返回0
行,或者将它初始化为一个非可选的空数组,然后您可以一直请求它的count
。
一般来说,对于这类问题,您不想集中精力防止cellForRowAtIndexPath
被调用,而是计划在任何时候调用它,并在后台任务尚未完成时返回合理的结果(如报告表有0行)。