这是我的班级:
import UIKit
import SwiftyJSON
class ListOfEvents: UIViewController, UITableViewDataSource, UITableViewDelegate {
var tableView:UITableView?
var items = NSMutableArray()
override func viewDidLoad() {
let frame:CGRect = CGRect(x: 0, y: 100, width: self.view.frame.width, height: self.view.frame.height-100)
self.tableView = UITableView(frame: frame)
self.tableView?.dataSource = self
self.tableView?.delegate = self
self.view.addSubview(self.tableView!)
print("aaa")
getAllRequests()
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.items.count;
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
tableView.registerClass(SingleEventCell.self, forCellReuseIdentifier: "cell")
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! SingleEventCell
let user:JSON = JSON(self.items[indexPath.row])
print(user["username"].description)
// cell.username.text = user["username"].description
// cell.descr.text = "ggg"
print(cell)
return cell
}
func getAllRequests() {
print("getAllRequests")
RestApiManager.sharedInstance.getRequests { json in
let results = json//["username"]
for (index: String, subJson: JSON) in results {
let user: AnyObject = JSON.object
self.items.addObject(user)
dispatch_async(dispatch_get_main_queue(),{
self.tableView?.reloadData()
})
}
}
}
}
我尝试使用从webservice获取的数据填充我的自定义UITableViewCell
。我的问题是:
print(user["username"].description) //that prints perfectly
但如果我取消注释以下其中一行:
// cell.username.text = user["username"].description
// cell.descr.text = "ggg"
我收到错误:
fatal error: unexpectedly found nil while unwrapping an Optional value
我怀疑在尝试初始化/可见算法之前我会尝试引用这些单元格,但如果是这样的话 - 我该如何防止它?我使用的是viewDidLoad()
方法,但这并没有改变任何内容 - 错误仍然相同。
我该如何解决?
==== EDIT
导入UIKit 导入SwiftyJSON
tableview
但现在当我运行它时,我得到了错误;
class ListOfEvents: UIViewController, UITableViewDataSource, UITableViewDelegate {
@IBOutlet weak var tview: UITableView!
var tableView:UITableView?
var items = NSMutableArray()
override func viewDidLoad() {
let frame:CGRect = CGRect(x: 0, y: 100, width: self.view.frame.width, height: self.view.frame.height-100)
tview = UITableView(frame: frame)
tview.dataSource = self
tview.delegate = self
self.view.addSubview(tview!)
print("aaa")
getAllRequests()
}
func tableView(tview: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.items.count;
}
func tableView(tview: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
tview.registerClass(SingleEventCell.self, forCellReuseIdentifier: "cell")
let cell = tview.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! SingleEventCell
let user:JSON = JSON(self.items[indexPath.row])
print(user["username"].description)
// cell.username.text = user["username"].description
cell.descr.text = "ggg"
print(cell)
return cell
}
func getAllRequests() {
print("getAllRequests")
RestApiManager.sharedInstance.getRequests { json in
let results = json
for (index: String, subJson: JSON) in results {
let user: AnyObject = JSON.object
self.items.addObject(user)
dispatch_async(dispatch_get_main_queue(),{
self.tview.reloadData()
})
}
}
}
}
这里:
fatal error: unexpectedly found nil while unwrapping an Optional value
有没有办法解决它?
答案 0 :(得分:2)
这一行有一个明显的问题:
tview = UITableView(frame: frame)
这不是您在代码中创建表视图的方式。您必须调用指定的初始化程序,即initWithFrame:style:
。例如:
tview = UITableView(frame: frame, style: .Plain)
但请注意,您的代码存在各种其他问题,这些问题也可能存在问题。例如,这一行:
let frame:CGRect = CGRect(x: 0, y: 100, width: self.view.frame.width, height: self.view.frame.height-100)
该行取决于具有帧的self.view
和足够大小的帧(即高度超过100个像素)。但是你不知道这一点,因为在viewDidLoad
,self.view
仅仅存在 - 它还没有达到它的最终帧,因为它尚未被放入界面中布局。所以那条线在那时非常危险。
答案 1 :(得分:0)
我猜你可能没有在username
内正确设置descr
和/或SingleEventCell
个插座。
看看here,了解如何正确连接插座。
答案 2 :(得分:0)
您的问题是,tableView.cellForRowAtIndexPath
想要加载它时尚未提取您的JSON对象,因此会出现意外发现的错误。
你可以做的是:
创建新的委托协议:
protocol NetworkingDelegate {
func didFinishLoadingData()
}
创建一个类Networking
,您可以将API请求放在:
class Networking {
var networkingDelegate: NetworkingDelegate?
// (I am using Alamofire here so the function itself will differ a little.)
func getAllRequests() {
Alamofire.request(.GET, "YOUR_API_ENDPOINT")
.responseJSON { response in
if response.result.isSuccess {
let jsonObject = JSON(response.result.value!)
User.populateUserDataSourceFromJSON(jsonObject)
self.dispatchAndRefresh()
}
}
}
}
func dispatchAndRefresh() {
dispatch_async(dispatch_get_main_queue()) {
if let delegate = self.networkingDelegate {
delegate.didFinishLoadingData()
}
}
}
在你的Modelclass中有一个名为populateUserDataSourceFromJSON
的函数class User {
let name = String()
let age = Int()
//...
init() {
}
class func populateUserDataSourceFromJSON(json: JSON) {
userDataSource = [User]()
for (_, user): (String, JSON) in json {
let currentUser = User()
currentUser.name = user["name"].stringValue
currentUser.age = user["age"].intValue
//...
userDataSource.append(currentUser)
}
}
在ViewController中添加我们创建的代理:
class ListOfEvents: UIViewController, UITableViewDataSource, UITableViewDelegate, NetworkingDelegate {
//...
创建Networking类的引用:
let networking = Networking()
并将其委托给自己:
override func viewDidLoad() {
super.viewDidLoad()
networking.networkingDelegate = self
//...
唯一要做的就是通过实现didFinishloadingData()
使ViewController符合Delegatefunc didFinishLoadingData() {
tableView.reloadData()
}
我希望这会有所帮助。