它会抛出错误"索引超出范围"当我尝试从字典中删除一个值

时间:2017-01-08 19:28:53

标签: ios swift uitableview nsdictionary

我是新手程序员,而且还没有才华,我陷入了错误,我无法处理好几天。我对indexpath有疑问,当我尝试从Dictionary删除某些内容时,它会引发错误,“fatal error: Index out of range“

简单地说,我在下面显示了我的dictionarytableviewnumberofrows和成员可能会增加或减少,我在检查其中一个时将这些成员添加到字典中在tableview上,它添加了一个没有任何问题。但是当我删除我选择的一个时问题开始了,我认为原因是索引号,因为它们的索引号在包含在字典中时会发生变化。我想删除我选择的确切人物,但它是如何实现的?

例如,当我通过取消选中person3删除时,字典中只能有person1和person5。如果代码和错误不明确,请告诉我。

这就是我的tableview,成员列表的外观;

1. person1 ✔️   // -> index 0 
2. person2
3. person3 ✔️   // -> index 2
4. person4
5. person5 ✔️   // -> index 4

选择的词语已添加到词典

var selectedUser = [NSDictionary?]()   
var friendsDic = [NSDictionary?]()

// Inside of selectedUser after the adding members.
[{
    email = “person1@gmail.com";    
    id = jqvDUcBoV9Y4sxir5kR0dg1;   // person1 index is still 0 
    name = person1;
    profileImageUrl = "<null>";
}, {
    email = “person5@gmail.com";    // Now person5 index is 1
    id = hVfS9EU6LWatAynJNyDmum4A2;
    name = person5;
    profileImageUrl = "https://firebasestorage.googleapis.com/v0/b/findyourfrienddemo.appspot.com/o/profile_images%2FAE5ED4E4-CF53-4AC4B628.jpg?alt=media&token=eb969e-57290d7e02c9";
}, {
    email = “person3@gmail.com";    // and person3 index is 2 
    id = 6LwvafOJLSQsbhJwu8MJjYI3;
    name = person3;
    profileImageUrl = "<null>";
}]

这是我的全部代码:

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let cell = tableView.cellForRow(at: indexPath)
        let friendUser: NSDictionary?
        friendUser = friendsDic[indexPath.row]
        if cell!.isSelected {
            cell!.isSelected = false
            if cell!.accessoryType == UITableViewCellAccessoryType.none {
                cell!.accessoryType = UITableViewCellAccessoryType.checkmark
            }
            else {
                cell!.accessoryType = UITableViewCellAccessoryType.none
            }
        }

        if cell!.accessoryType == UITableViewCellAccessoryType.checkmark {
            let named = friendUser?["name"] as! String
            let urlImg = friendUser?["profileImageUrl"] as? String
            let id = friendUser?["id"] as! String
            let email = friendUser?["email"] as! String
            let dicc: [String: String?] = ["name": named, "email": email, "id": id, "profileImageUrl": urlImg]

            databaseRef.child("selectedfriends").child(id).child(CurrentUserID!).setValue(true)

            selectedUser.append(dicc as NSDictionary) 
            MapPage.selectedUsersInfo = selectedUser as! [NSDictionary]
        }

        if cell!.accessoryType == UITableViewCellAccessoryType.none {
            let id = friendUser?["id"] as! String
            databaseRef.child("selectedfriends").child(id).child(CurrentUserID!).setValue(false)

            var i = indexPath.row
            selectedUser.remove(at: i)

            MapPage.selectedUsersInfo = selectedUser as! [NSDictionary] 
     }
}

1 个答案:

答案 0 :(得分:0)

您发布的代码没有意义。看起来你有一个数据结构friendsDic,它是一个字典数组,包含表视图中每个单元格的条目。

当用户选择一个单元格时,您从该单元格的friendsDic条目中提取字段,并使用这些字段构建一个新的字典,并将其追加到数组selectedUser的末尾。

当用户取消选择单元格时,您尝试使用表格视图中单元格的行从selectedUser中删除该条目,但selectedUser数组的元素将不在任何特定的顺序(它们将按用户检查它们的顺序排列。)即使它们确实与friendsDic数组中的条目的顺序相同,数组索引也会赢得&#39 ; t匹配,因为来自friendsDic的未选定项目不在selectedUser数组中。这就是为什么你的索引超出范围错误。

在我看来,你的设计存在缺陷,需要重新设计。

您需要退后一步,在更高级别解释您尝试执行的操作(应用程序功能),然后逻辑地说明您尝试实现该功能的方式。

编辑:

请停止将您的数据模型描述为字典。不是。你有一个阵列。数组的元素是字典。正如Hamish在评论中所说,一系列结构将是更好的选择,但你可以使一系列字典工作。

我建议不要尝试维护第二组选定项目。您可以设置表视图以支持多个选择,然后使用方法indexPathsForSelectedRows获取所选行的索引路径数组。