我有一个按钮可以删除它所在的单元格。数据模型工作正常,tableView.reloadData() 没有导致错误。但是,当我使用 tableView.deleteRowsAtIndexPaths(..) 时,发生崩溃并告诉我以下信息:
-[__NSCFNumber row]: unrecognized selector sent to instance 0xb000000000000003
2014-10-29 03:37:08.999 SampleApp[4915:82542] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFNumber row]: unrecognized selector sent to instance 0xb000000000000003'
指示发生这种情况的代码如下所示。我有一种感觉,它与我的通知有关,但我不知道为什么。我在发布通知时尝试使用 nil 作为 object 的参数,但这没有什么区别。我不明白为什么 tableView.reloadData() 会起作用,而替代方法不会。我怎样才能阻止这种情况发生?
GoalTableViewCell 继承自 UITableViewCell 的类(节选)
@IBAction func deleteButtonTapped(sender: AnyObject) { //IBAction is connected to a delete button within the cell.
let index = self.indexInTable //indexInTable is an Int property that tracks where the cell is located in the tableView. It is updated using cellForRowAtIndexPath(..)
var userInfo = ["index" : index]
NSNotificationCenter.defaultCenter().postNotificationName("DeletedGoal", object: self, userInfo: userInfo)
}
GoalsTableViewController 继承自 UIViewController 的类(其中有一个 tableView)(摘录)
func deletedGoal(notification : NSNotification) {
if (notification.name == "DeletedGoal") {
var userInfo = notification.userInfo!
var index = userInfo["index"] as Int //this is returning the proper index.
goalsArray.removeAtIndex(index)
saveGoals(goalsArray)
//self.tableView.reloadData() //this works.
self.tableView.deleteRowsAtIndexPaths([index], withRowAnimation: UITableViewRowAnimation.Fade) //this causes error
}
}
编辑:我更正了代码(非常感谢各位),但遇到了一个新错误。我可能会为此提出一个新问题:在连续删除更多单元格后,我最终遇到崩溃,告诉我 indexPath 太高。我猜 cellForRowAtIndexPath(..) 是问题所在,它不会标记单元格的 indexInTable 属性,除非发生滚动(?)
//correct code
func deletedGoal(notification : NSNotification) {
if (notification.name == "DeletedGoal") {
var userInfo = notification.userInfo!
//var cell = userInfo["cell"] as GoalTableViewCell
var index = userInfo["index"] as Int
println(index)
goalsArray.removeAtIndex(index)
saveGoals(goalsArray)
let indexPath = NSIndexPath(forRow:index,inSection:0)
self.tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Fade)
//self.tableView.reloadData()
}
}
请您参考如下方法:
如果您查看异常消息,您将看到 [__NSCFNumber row],它告诉您有人试图在 NSCFNumber 上调用 row 方法(这是一个NSNumber) 的内部类 - 它没有行方法。
现在看看 self.tableView.deleteRowsAtIndexPaths([index], withRowAnimation: UITableViewRowAnimation.Fade) - 方法名称告诉您(或者您可以阅读文档)它需要一个 NSIndexPath不是NSNumber
所以,你想说的是
self.tableView.deleteRowsAtIndexPaths([NSIndexPath(forRow:index inSection:0)], withRowAnimation:UITableViewRowAnimation.Fade)
这是假设您的表格只有一个部分。如果它有多个部分,那么您将需要跟踪单元格中的部分编号以及行。为此,您可以将存储的属性更改为 indexPath 而不是 IndexPath.row。
然后你可以说
@IBAction func deleteButtonTapped(sender: AnyObject) { //IBAction is connected to a delete button within the cell.
let index = self.indexInTable //indexInTable is an NSIndexPath property that tracks where the cell is located in the tableView. It is updated using cellForRowAtIndexPath(..)
var userInfo = ["index" : index]
NSNotificationCenter.defaultCenter().postNotificationName("DeletedGoal", object: self, userInfo: userInfo)
}
func deletedGoal(notification : NSNotification) {
if (notification.name == "DeletedGoal") {
var userInfo = notification.userInfo!
var index = userInfo["index"] as NSIndexPath
goalsArray.removeAtIndex(index.row)
saveGoals(goalsArray)
//self.tableView.reloadData() //this works.
self.tableView.deleteRowsAtIndexPaths([index], withRowAnimation: UITableViewRowAnimation.Fade) //this causes error
}
}
