从 Realm 数据库中删除对象。

3
我正在编写一款Todo应用程序。该应用程序很简单,共有两个页面。一个页面用于以表格视图形式显示任务,另一个页面用于添加新任务。在添加新任务的页面中,我会将其发布到服务器,然后在主页面中从服务器获取数据,并在realm数据库中保存数据。
当我想要在主页面中删除这些任务时,我的应用程序会崩溃,并显示以下错误信息。
  Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[TodoApp.TodosTableViewController delete:]: unrecognized selector sent to instance 0x7fca7b40b4c0

有人知道为什么吗? 这是我的删除功能:

public func delete<T:Object>(_ model: T) {
    let realm = try! Realm()
    
    try! realm.write {
        
        realm.delete(model)
        
        }
}

这是我使用该函数从数据库中删除的位置:

override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath){
        
        if editingStyle == UITableViewCellEditingStyle.delete {
            rowHere = indexPath.row
            // it crashes the app when I want to delete from database
            
//            delete(self.todos[self.rowHere!])
            
            self.todos.remove(at: indexPath.row)
            tableView.deleteRows(at: [indexPath as IndexPath], with:           UITableViewRowAnimation.automatic)
            
            
            
        }
    }

我感到困惑。为什么在调用此函数之前你没有一个 Realm 实例?如果你是使用一个 Realm 实例创建的,那么你应该从同一个实例中删除它。 - Mozahler
你的函数 delete() 存在于哪里?它是你的 TodosTableViewController 类的一个方法吗? - AustinZ
@Mozahler,我有用于在数据库中删除、读取和保存的全局函数。这就是为什么每次我创建一个新对象。我已经检查了你的想法,但它不起作用。 - Amirhossein Hashemi
@AustinZ 我的删除对象不在TodosTableViewController中。它是一个全局函数,不属于任何类。 - Amirhossein Hashemi
你的代码失败的原因就在这里。你试图调用一个不存在的表视图控制器方法。 - AustinZ
4个回答

3
我在我的应用程序中实现了类似的功能,希望能帮到你。
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
    //deleteRecords()
    delete(index: indexPath.row)
    retrieveFoods()
    tableView.reloadData()
}

func retrieveFoods() {
    let realm = try! Realm()
    myFoodsArray = realm.objects(MyFoods.self).sorted(byKeyPath: "name", ascending: true)
}

func delete(index: Int) {
    let myFood = myFoodsArray[index]
    let realm = try! Realm()
    try! realm.write {
        realm.delete(myFood)
        self.tableView.reloadData()
    }
}

这个函数 delete(index: Int) 只是删除了选定的项目,而不是从 Realm 数据库中删除吗? - Abrcd18
应该从数据库中删除,使用realm.delete(myFood)。 - JP Aquino

1
在 `viewDidLoad()` 中首先获取对象模型。保留 HTML,不做解释。
var DatabaseModel: Results<ObjectClassRealm>!

override func viewDidLoad() {
    super.viewDidLoad()
    let realm = RealmService.shared.realm
    DatabaseModel = realm.objects(ObjectClassRealm.self)
}


func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) { 
    guard editingStyle == .delete else { return }
    let objectData = DatabaseModel[indexPath.row]
    RealmService.shared.delete(objectData)
}

或者你可以在按钮点击时删除

@IBAction func DeleteData(_ sender: Any) {
    let realm = try! Realm()
    let deleteData = realm.object(ofType: ObjectClassRealm.self, 
                                  forPrimaryKey: PRIMARYKEY)
    if deleteData == nil {
        print("No data in DB")
    } else {
        RealmService.shared.delete(deleteData!)
    }
}

0

我认为错误信息是误导性的。 你没有展示在哪里定义了类属性rowHere(作为整数),但这个变量在这里是不需要的。

delete(self.todos[self.rowHere!])

如果todos是你的Realm对象子类的数组,那么这应该可以工作:
   let objectToDelete = self.todos[indexPath.row]
   delete(objectToDelete])

只要你的删除操作类似于这样:(我的 Realm 实例称为 realmStore)
func delete(objectToDelete: Object) // use your subclass name
    do {
       try realmStore.write {
          realmStore.delete(record)
       }
    } catch {
       print("Could not delete object.\n\(String(describing: error.localizedDescription))"
}

0
我发现问题来自于“delete”这个词。似乎这个单词在Xcode中被保留。当我调用它时,它会到另一个不属于我的方法中去。我把名称改成了比如deleteSomethings,然后它就起作用了。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接