【发布时间】:2014-12-09 22:21:42
【问题描述】:
我正在编写我的第一个 iOS 应用程序,并且正在学习协议和委托。该应用程序是一个基本的随机响应生成器。当用户摇动设备或点击屏幕时,随机响应应显示在标签中。
目前,我在导航控制器中嵌入了三个视图控制器:MainViewController.swift、SettingsViewController.swift 和 ResponsesViewController.swift。
我在MainViewController.swift 中有一个包含响应的数组。我已经成功地将数据传递给第三个视图控制器,即ResponsesViewController.swift,这是一个用于显示存储响应的表格视图。我已将我的第一个视图控制器 MainViewController 设置为我的第三个视图控制器 ResponsesViewController 的委托,并实现了我想从数据模型(responses 数组)中删除所选响应的方法。
我的问题是当我尝试删除一个回复时,我在控制台中收到了fatal error: Cannot index empty buffer。我使用println(responses.count) 确保将数组成功传递给第二个和第三个视图控制器。我在方法viewDidLoad()、viewWillAppear() 和viewDidDisappear() 中的所有三个视图控制器中都放置了println(responses.count) 语句。这表明数据已成功传递,因为数组中有 3 个对象,每个 println() 语句。但是,在我的代表MainViewController.swift 中,当我尝试从数据模型中删除选定的响应时,我不断收到错误消息。我将println(responses.count) 放入此方法中,但它不断返回0 并因错误而崩溃。只有在委托中调用 func responsesViewController(controller: ResponsesViewController, didDeleteResponseAtIndexPath indexPath: NSIndexPath) 时才会发生这种情况 (MainViewController.swift)
这是我的代码:
MainViewController.swift
var responses: [Response] = []
let response1 = Response(text: "String 1")
let response2 = Response(text: "String 2")
let response3 = Response(text: "String 3")
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.navigationBarHidden = true
responses += [response1, response2, response3]
}
* delegate *
func responsesViewController(controller: ResponsesViewController, didDeleteResponseAtIndexPath indexPath: NSIndexPath) {
responses.removeAtIndex(indexPath.row)
}
ResponsesViewController.swift
protocol DeleteResponseDelegate {
func responsesViewController(controller: ResponsesViewController, didDeleteResponseAtIndexPath indexPath: NSIndexPath)
}
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == .Delete {
delegate?.responsesViewController(self, didDeleteResponseAtIndexPath: indexPath)
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)
tableView.reloadData()
}
}
-编辑-
事实证明,我只需将数组从我的第三个视图控制器传递回我的第一个视图控制器即可解决我的问题。我显然对授权感到困惑。这是我更新的代码,我从数组中删除了该项目,然后将该数组传递回第一个视图控制器:
ResponsesViewController.swift
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == .Delete {
responses.removeAtIndex(indexPath.row)
let mainViewController = navigationController?.viewControllers.first as MainViewController
mainViewController.responses = self.responses
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)
tableView.reloadData()
}
}
【问题讨论】:
-
对不起,如果我遗漏了什么,但响应是空的,不是吗?即响应1!=响应[0]
-
@chris 我添加了将三个字符串对象插入数组的代码。
-
所以我收集你将数据传递给其他视图很好,你是如何将它传递回来的?
-
好问题。我假设 MainViewController 中的响应数组仍然包含创建它的对象。这是不正确的吗?数据是否跨视图控制器传输并且始终只有一个数组实例?这对我来说很有意义,为什么在尝试删除委托中的选定响应时它会是空的。