ios - 只能从它属于 Swift 的 Realm 中删除一个对象
问题描述
我正在尝试在我的 NotesApp 中从领域中删除笔记并遇到此错误:“只能从它所属的领域中删除一个对象”。这条笔记之前也保存在 Realm 中,并且可以通过点击我的 FSCalendar 中的日期在我的 TableView 中显示它。我试图用realm.create(item)替换realm.add(item),但也得到了错误:“无法将'T'类型的值转换为预期的参数类型'Object.Type'(又名'RealmSwiftObject.Type') ”。我是编程新手,所以任何帮助将不胜感激。这是相关的代码代码:
in my ToDoListItem.swift
class ToDoListItem: Object {
@objc dynamic var noteName: String = ""
@objc dynamic var date: Date = Date()
@objc dynamic var descriptionText: String = ""
@objc dynamic var noteImage = Data()
init(date: Date, noteName: String) {
self.date = date
self.noteName = noteName
}
override init() {
self.noteName = ""
self.date = Date()
self.descriptionText = ""
self.noteImage = Data()
}
}
in my RealmManager.swift
class RealmManager {
static let shared = RealmManager()
private let realm = try! Realm()
func write<T: Object>(item: T) {
realm.beginWrite()
realm.add(item)
try! realm.commitWrite()
}
func getObjects<T: Object>(type: T.Type) -> [T] {
return realm.objects(T.self).map({ $0 })
}
func delete<T: Object>(item: T) {
try! realm.write {
realm.delete(item)
}
}
}
in my ViewController where i can edit and delete the notes
@IBAction func didTapDelete() {
let note = ToDoListItem()
RealmManager.shared.delete(item: note)
self.deletionHandler?()
navigationController?.popToRootViewController(animated: true)
}
and finally in my TableViewController where the notes are displayed (honestly i think the problem is hidden here but cannot find it...
@IBOutlet var tableViewPlanner: UITableView!
@IBOutlet var calendarView: FSCalendar!
private var data = [ToDoListItem]()
var datesOfEvents: [String] {
return self.data.map { DateFormatters.stringFromDatestamp(datestamp: Int($0.date.timeIntervalSince1970)) }
}
var items: [ToDoListItem] = []
func getCount(for Date: String) -> Int {
var count: [String : Int] = [:]
for date in datesOfEvents {
count[date] = (count[date] ?? 0) + 1
}
return count[Date] ?? 0
}
func getEventsForDate(date: Date) -> [ToDoListItem] {
let string = DateFormatters.stringFromDatestamp(datestamp: Int(date.timeIntervalSince1970))
return self.data.filter {DateFormatters.stringFromDatestamp(datestamp: Int($0.date.timeIntervalSince1970)) == string }.sorted(by: {$0.date < $1.date})
}
override func viewDidLoad() {
super.viewDidLoad()
calendarView.rounding()
tableViewPlanner.rounding()
data = RealmManager.shared.getObjects(type: ToDoListItem.self)
self.items = self.getEventsForDate(date: Date())
calendarView.delegate = self
calendarView.dataSource = self
tableViewPlanner.delegate = self
tableViewPlanner.dataSource = self
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
self.calendarView.select(Date())
self.calendarView.reloadData()
refresh()
}
//MARK:- TableView Data Source
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.items.count //data.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: K.plannerCellIdentifier, for: indexPath) as! NoteTableViewCell
let note = self.items[indexPath.row]
cell.configureCell(note: note)
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
let note = data[indexPath.row]
guard
let vc = storyboard?.instantiateViewController(identifier: K.infoVCIdentifier) as? InfoViewController else { return }
vc.note = note
vc.deletionHandler = { [weak self] in
self?.refresh()
}
vc.title = note.noteName
navigationController?.pushViewController(vc, animated: true)
}
//MARK:- User Interaction
@IBAction func didTapAddButton() {
guard
let vc = storyboard?.instantiateViewController(identifier: K.entryVCIdentifier) as? EntryViewController else { return }
vc.completionHandler = { [weak self] in
self?.refresh()
}
vc.title = K.entryVCTitle
navigationController?.pushViewController(vc, animated: true)
}
func refresh() {
DispatchQueue.main.async {
self.data = RealmManager.shared.getObjects(type: ToDoListItem.self)
self.tableViewPlanner.reloadData()
self.calendarView.reloadData()
}
}
}
扩展 PlannerViewController: FSCalendarDelegateAppearance & FSCalendarDataSource {
func calendar(_ calendar: FSCalendar, appearance: FSCalendarAppearance, eventDefaultColorsFor date: Date) -> [UIColor]? {
let dateString = DateFormatters.yearAndMonthAndDateFormatter.string(from: date)
if self.datesOfEvents.contains(dateString) {
return [UIColor.blue]
}
return [UIColor.white]
}
func calendar(_ calendar: FSCalendar, didSelect date: Date, at monthPosition: FSCalendarMonthPosition) {
self.items = self.getEventsForDate(date: date)
self.tableViewPlanner.reloadData()
}
func calendar(_ calendar: FSCalendar, numberOfEventsFor date: Date) -> Int {
let dateString = DateFormatters.yearAndMonthAndDateFormatter.string(from: date)
let count = self.getCount(for: dateString)
self.tableViewPlanner.reloadData()
return count
}
}
解决方案
真正的问题是 didTapDelete 函数——你为什么要创建一个新注释只是为了删除它(我希望它只是为了测试领域删除语法)。您应该删除传递给视图控制器以进行编辑/删除的注释对象。(确实选择行中的 vc.note -> 另一个 VC 中的 self.note - didTapDelete 所在的位置)所以您的点按删除看起来像-
RealmManager.shared.delete(item: note)
//show deleted alert & go back
关于错误的一点解释 - 只是实例化一个 Realm 对象 (ToDoListItem()) 不会将它添加到 Realm(数据库系统)。要删除/编辑领域对象,必须从领域中获取(RealmManager.shared.getObjects(type: ToDoListItem.self))或添加到领域。
我建议在跳入代码之前先阅读 Realm 教程(有很多)
推荐阅读
- javascript - 有没有办法在没有选框标签的情况下制作类似于 DVD 屏幕保护程序的 HTML 元素?
- javascript - 在页面重新加载之前执行 http 请求
- spring-boot - 如何对我的服务类进行删除测试?
- sql - 在雪花的最终结果集中需要不同的列名
- java - 如何从 Firebase 实时数据库中检索具有 UID 的特定用户的特定数据
- vb.net - 是否可以在visual basic中获得下周一和周日的日期?
- python - 数组中的 Python 对象
- salt-stack - 如何在不运行命令的情况下检查命令将针对哪些奴才?
- java - 更新数组列表的最佳实践(Java/Spring Boot)
- mysql - MySQL - 总和正在成倍增加