我有一个应用程序从JSON数据加载问题列表并在TableView上显示它们。
大部分时间一切正常,但似乎我做错了,这就是为什么 - 应用程序崩溃。
它很少发生,因此难以检测,但我确信逻辑必定存在问题。
所以我有问题项的问题和数组的模型类:
class questionItem {
var id = 0
var title : String = ""
var question : String = ""
}
var questions = [questionItem]()
在我的ViewController中我有TableView的IBOutlet,我将数据加载到viewDidLoad中
class QuestionsListVC: UIViewController, UITableViewDataSource, UITableViewDelegate {
@IBOutlet weak var questionsTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
get_questions()
}
func get_questions()
{
let request = NSMutableURLRequest(URL:myURL!)
request.HTTPMethod = "POST"
let postString = ""
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request)
{
data, response, error in
if error != nil {
print("error=\(error)")
return
}
//clearing array for new items
questions.removeAll(keepCapacity: false)
dispatch_async(dispatch_get_main_queue(),{
var json = JSON(data: data!)
if let items = json["questions"].array {
for item in items {
let question = questionItem()
question.id = item["id"].int!
question.title = item["title"].string!;
question.question = item["question"].string!
questions.append(question)
}
}
self.questionsTableView.reloadData()
});
}
task.resume()
}
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
return questions.count
}
错误显示在cellForRowAtIndexPath
中func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell : QuestionsListCell = self.questionsTableView.dequeueReusableCellWithIdentifier("QuestionsListCell") as! QuestionsListCell
//error happens here - Index out of range
print(questions[indexPath.row].title)
在6个案例中发生了一次,并且在6个测试中的其他5个中没有错误 - 但我不明白为什么。
答案 0 :(得分:1)
这指出了
的问题numberOfSectionsInTableView
和/或
numberOfRowsInSection
你能发布这些当前的实现吗?
如果只显示一个连续列表,则numberOfSectionsInTableView应始终返回1,并且您需要检查numberOfRowsInSection是否准确返回数据源中的项目数。
修改强>
您是否可以在使用新项目更新之前立即清除主线程上的现有数据源,如下面的代码所示:
dispatch_async(dispatch_get_main_queue(),{
questions.removeAll(keepCapacity: false)
var json = JSON(data: data!)
if let items = json["questions"].array {
for item in items {
let question = questionItem()
question.id = item["id"].int!
question.title = item["title"].string!;
question.question = item["question"].string!
questions.append(question)
}
}
self.questionsTableView.reloadData()
});
答案 1 :(得分:1)
您的代码中对questions.removeAll
的调用会使以下事件序列成为可能:
numberOfRowsInSection
之前调用questions.removeAll
,返回旧的非零容量questions.removeAll
清除questions
cellForRowAtIndexPath
之前调用questions
,导致索引超出范围异常一种解决方法是相对简单的:制作一个newQuestions
数组,在get_questions
中填充它,并在调用numberOfRowsInSection
时将其交换:
// Add this to your class
var newQuestions : [questionItem]
// Change get_questions:
dispatch_async(dispatch_get_main_queue(), {
var json = JSON(data: data!)
if let items = json["questions"].array {
var tmpQuestions = [questionItem]()
for item in items {
let question = questionItem()
question.id = item["id"].int!
question.title = item["title"].string!;
question.question = item["question"].string!
tmpQuestions.append(question)
}
newQuestions = tmpQuestions
self.questionsTableView.reloadData()
}
});
// Change numberOfRowsInSection
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
if newQuestions != nil {
questions = newQuestions
newQuestions = nil
}
return questions.count
}
请注意get_questions
如何不直接填充newQuestions
。相反,它会构建tmpQuestions
,并仅在完全构建时将其设置为newQuestions
。
答案 2 :(得分:0)
尝试使用以下代码,
find . -name \*.txt -maxdepth 1 -print0 | xargs -0 -n 1000 rename ....
使用此方法更改cellForRow。希望这会对你有所帮助。
答案 3 :(得分:0)
为了避免崩溃,我会添加以下三项安全检查。
<强> 1。清除前检查阵列计数。
if questions.count > 0
{
questions.removeAll()
}
<强> 2。在表重新加载
之前检查数组计数if questions.count > 0
{
self.questionsTableView.reloadData()
}
第3。在cellForRowAtIndex方法中,在放入Cell之前检查对象数组中的值
if let objModel : questionItem = questions[indexPath.row] as? questionItem
{
print(" title is \(objModel.title)")
}