UITableView 在 tableview.datasource 开始时崩溃
Posted
技术标签:
【中文标题】UITableView 在 tableview.datasource 开始时崩溃【英文标题】:UITableView crashes at start at tableview.datasource 【发布时间】:2017-02-04 02:17:40 【问题描述】:我在单独的 ViewController 类中实现了两个 UITableview。成功添加第二个 UItableView 的代码后,我的项目构建但加载后停止。
它以一条红线停止:
tableView.delegate.dataSource = self
出现如下错误:
线程 1 EXEC_BAD_INSTRUCTION (code-EXC_i386_INVOP,subcode=0x0)
与
致命错误:在展开可选值时意外发现 nil
由于直到在第二个视图控制器中添加第二个 UItableview 才发生这种情况,我想知道我的代码是否相互冲突。我将发布两个视图控制器的副本。我应该改变什么?
顺便说一句:FilmsViewController 是应用程序崩溃的地方。虽然在添加 MCViewController 电影之前它可以工作:
乙:
class FilmsViewController: UIViewController, UITableViewDataSource, UITableViewDelegate
weak var tableView : UITableView!
var FilmArray = [String]()
let film_url = "https://www.testing.com/api/resources/films/1"
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return FilmArray.count
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: "mycell", for:indexPath) as! FilmsAPITableViewCell
// Configuring Cell
cell.movieTitle.text = FilmArray[indexPath.row]
// Returning the cell
return cell
override func viewDidLoad()
super.viewDidLoad()
tableView.dataSource = self
tableView.delegate = self
let url:URL = URL(string: film_url)!
let session = URLSession.shared
let request = NSMutableURLRequest(url: url)
request.httpMethod = "GET"
request.setValue("740c94c51891c02b64d6c78840b478fe0b02fe2c", forHTTPHeaderField: "X-API-KEY")
request.setValue("Basic YmhlZW0uZW5nckBnbWFpbC5jb206YmgzM20=", forHTTPHeaderField: "Authorization")
request.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringCacheData
let paramString = ""
request.httpBody = paramString.data(using: String.Encoding.utf8)
let task = session.dataTask(with: request as URLRequest, completionHandler:
(
data, response, error) in
guard let _:Data = data, let _:URLResponse = response , error == nil else
return
var json:Any?
do
if let existingData = data
json = try JSONSerialization.jsonObject(with: existingData, options: [])
// Prasing JSON
if let parsedData = json as? [[String:Any]]
for dict in parsedData
if let title = dict["title"] as? String
self.FilmArray.append(title)
print(json)
OperationQueue.main.addOperation(
self.tableView.reloadData()
)
catch
return
guard let server_response = json as? NSDictionary else
return
if let data_block = server_response["data"] as? NSDictionary
if let session_data = data_block["session"] as? String
// self.login_session = session_data
let preferences = UserDefaults.standard
preferences.set(session_data, forKey: "session")
// DispatchQueue.main.async(execute: self.LoginDone)
)
task.resume()
// Do any additional setup after loading the view.
override func didReceiveMemoryWarning()
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
MC:
class MCViewController: UIViewController, UITableViewDataSource, UITableViewDelegate
let message_url = "https://www.testing.com/api/resources/get_film_message/film_id/3825"
let send_url = "https://www.testing.com/api/resources/send_film_message"
let film_id = "3825"
var messageArray = [String]()
weak var tableView : UITableView!
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return messageArray.count
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: "msgContent", for:indexPath) as! MessageTableViewCell
// Configuring Cell
cell.msgContent.text = messageArray[indexPath.row]
// Returning the cell
return cell
@IBOutlet weak var MessageInput: UITextField!
@IBAction func Sendmsg(_ sender: Any)
Sendmsg(username:MessageInput.text!, password: film_id)
override func viewDidLoad()
super.viewDidLoad()
tableView.dataSource = self
tableView.delegate = self
// Do any additional setup after loading the view.
//let post_data: NSDictionary = NSMutableDictionary()
// post_data.setValue(username, forKey: "username")
// post_data.setValue(password, forKey: "password")
let url:URL = URL(string: message_url)!
let session = URLSession.shared
let request = NSMutableURLRequest(url: url)
request.httpMethod = "GET"
request.setValue("740c94c51891c02b64d6c78840b478fe0b02fe2c", forHTTPHeaderField: "X-API-KEY")
request.setValue("Basic YmhlZW0uZW5nckBnbWFpbC5jb206YmgzM20=", forHTTPHeaderField: "Authorization")
request.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringCacheData
// Do any additional setup after loading the view.
var paramString = ""
// for (key, value) in post_data
//
// paramString = paramString + (key as! String) + "=" + (value as! String) + "&"
//
//
request.httpBody = paramString.data(using: String.Encoding.utf8)
let task = session.dataTask(with: request as URLRequest, completionHandler:
(
data, response, error) in
guard let _:Data = data, let _:URLResponse = response , error == nil else
return
let json: Any?
do
json = try JSONSerialization.jsonObject(with: data!, options: [])
if let parsedData = json as? [[String:Any]]
for dict in parsedData
if let title = dict["message"] as? String
self.messageArray.append(title)
print(json)
catch
return
guard let server_response = json as? NSDictionary else
return
if let data_block = server_response["data"] as? NSDictionary
if let session_data = data_block["session"] as? String
// self.login_session = session_data
let preferences = UserDefaults.standard
preferences.set(session_data, forKey: "session")
// DispatchQueue.main.async(execute: self.LoginDone)
)
task.resume()
override func didReceiveMemoryWarning()
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
func Sendmsg(username:String, password:String)
let post_data: NSDictionary = NSMutableDictionary()
post_data.setValue(username, forKey: "message")
post_data.setValue(password, forKey: "film_id")
let url:URL = URL(string: send_url)!
let session = URLSession.shared
let request = NSMutableURLRequest(url: url)
request.httpMethod = "POST"
request.setValue("740c94c51891c02b64d6c78840b478fe0b02fe2c", forHTTPHeaderField: "X-API-KEY")
request.setValue("Basic YmhlZW0uZW5nckBnbWFpbC5jb206YmgzM20=", forHTTPHeaderField: "Authorization")
request.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringCacheData
var paramString = ""
for (key, value) in post_data
paramString = paramString + (key as! String) + "=" + (value as! String) + "&"
request.httpBody = paramString.data(using: String.Encoding.utf8)
let task = session.dataTask(with: request as URLRequest, completionHandler:
(
data, response, error) in
guard let _:Data = data, let _:URLResponse = response , error == nil else
return
let json: Any?
do
json = try JSONSerialization.jsonObject(with: data!, options: [])
print(json)
catch
return
guard let server_response = json as? NSDictionary else
return
// if let data_block = server_response["data"] as? NSDictionary
//
// if let session_data = data_block["session"] as? String
//
// self.login_session = session_data
//
// let preferences = UserDefaults.standard
// preferences.set(session_data, forKey: "session")
//
// DispatchQueue.main.async(execute: self.LoginDone)
//
//
//
)
task.resume()
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
*/
【问题讨论】:
【参考方案1】:你在哪里初始化tableView
?好像是nil
....
tableView = UITableView(frame: frame)
如果您使用的是故事板/xib,您还可以将tableView
挂钩为IBOutlet。
【讨论】:
tableView = UITableView(frame: frame)?我不确定我是否在调用它。你能再解释一下吗? 我应该在哪里称呼它? 我会在viewDidLoad
中调用它,然后再做任何其他事情。 frame
参数将是一个 CGRect
,具有您想要的 x,y 位置和宽度、高度。虽然我会小心地根据viewDidLoad
中的视图框架设置框架,因为尚未计算视图的框架。 tableView = UITableView()
在 viewDidLoad
中,然后在 tableView.frame = CGRect(x: yourX, y: yourY, width: yourWidth, height: yourHeight)
其他地方,例如在 viewDidAppear
中也可能是一个可行的选择。
我以前没有这个,只用一个就可以了。如果以前可以使用,我现在应该添加它吗?
我通过使用storyboard和IBOutlet for tableview修复了以上是关于UITableView 在 tableview.datasource 开始时崩溃的主要内容,如果未能解决你的问题,请参考以下文章
在 UITableView 中的 UINib 中重新加载 UITableView
使用 UITableView 在 UITableView 上自动滚动 UIImageView
如果 UITableView 在 UIScrollView 中,则无法在 UITableView 上执行滑动删除
如何在没有数组的 UITableView 中显示 UITableView Cell?