我有一个按钮可以删除它所在的单元格。数据模型工作正常,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作为对象的参数,但这并没有什么不同。我不明白为什么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)
}
继承自UIViewController的 GoalsTableViewController
类(并且其中包含一个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()
}
}
答案 0 :(得分:2)
如果查看异常消息,您将看到[__NSCFNumber row]
,它告诉您尝试在NSCFNumber上调用row
方法(这是NSNumber
的内部类) - 没有行方法。
现在看看self.tableView.deleteRowsAtIndexPaths([index], withRowAnimation: UITableViewRowAnimation.Fade)
- 方法名称告诉您(或者您可以阅读文档)它想要一个NSIndexPath
的数组而不是NSNumber
s
所以,你想说的是
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
}
}
答案 1 :(得分:1)
问题很可能是var index
被设置为int类型。
但是,方法deleteRowsAtIndexPaths
需要一个NSIndexPath
类型的对象,因为它在内部会调用传递路径上的选择器行。
在你的情况下,在Int上调用选择器,它不响应行选择器。创建一个索引路径,首先将索引作为您的行,然后您就可以了。 :D