我的应用因未捕获的异常而终止:
' RLMException',原因:'只能在写入事务中添加,删除或创建Realm中的对象 - 首先在RLMRealm实例上调用beginWriteTransaction。
我是Realm的新手,使用Swift 3,结构也在Swift 3中发生了变化。
以下是我的代码:
#import RealmSwift
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
var todoItem: ToDoItem?
switch indexPath.section {
case 0:
todoItem = todos.object(at: UInt(indexPath.row)) as? ToDoItem
case 1:
todoItem = finished.object(at: UInt(indexPath.row)) as? ToDoItem
default:
fatalError("What the fuck did you think ??")
}
let realm = try! Realm() // 1
try! realm.write { () -> Void in
todoItem?.finished = !todoItem!.finished
}
tableView.reloadData()
}
func didFinishTypingText(_ typedText: String?) {
if (typedText?.utf16.count)! > 0 {
let newTodoItem = ToDoItem()
newTodoItem.name = typedText!
let realm = try! Realm() // 1
try! realm.write { () -> Void in//
{
realm.add(newTodoItem as! Object)
}
tableView.reloadData()
}
class ToDoItem : RLMObject
{
/*Every property that should be fetched and stored
in the database also needs the dynamic keyword.
Also, set the default values for the properties.*/
dynamic var name = ""
dynamic var finished = false
convenience init(name: String) {
self.init()
self.name = name
}
}
var todos: RLMResults<Object> {
get {
let predicate = NSPredicate(format: "finished == false", argumentArray: nil)
return ToDoItem.objects(with: predicate)
}
}
var finished: RLMResults<Object> {
get {
let predicate = NSPredicate(format: "finished == true", argumentArray: nil)
return ToDoItem.objects(with: predicate)
}
}
/ -----------第二视图控制器-------- /
import UIKit
import RealmSwift
class RealmTableViewController: UITableViewController,AddViewControllerDelegate {
var todos: Results<Object> {
get {
let predicate = NSPredicate(format: "finished == false", argumentArray: nil)
return ToDoItem.objects(with: predicate)
}
}
var finished: Results<Object> {
get {
let predicate = NSPredicate(format: "finished == true", argumentArray: nil)
return ToDoItem.objects(with: predicate)
}
}
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "CellIdentifier")
setupNavigationBar()
}
func setupNavigationBar() {
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(RealmTableViewController.addButtonAction))
}
func addButtonAction() {
let addViewController = AddViewController(nibName: nil, bundle: nil)
addViewController.delegate = self
let navController = UINavigationController(rootViewController: addViewController)
present(navController, animated: true, completion: nil)
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 2
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
switch section {
case 0:
return Int(todos.count)
case 1:
return Int(finished.count)
default:
return 0
}
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
switch section {
case 0:
return "To do"
case 1:
return "Finished"
default:
return ""
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CellIdentifier", for: indexPath) as UITableViewCell
let index = UInt(indexPath.row)
switch indexPath.section {
case 0:
if let todoItem = todos.object(at: index) as? ToDoItem {
let attributedText = NSMutableAttributedString(string: todoItem.name)
attributedText.addAttribute(NSStrikethroughStyleAttributeName, value: 0, range: NSMakeRange(0, attributedText.length))
cell.textLabel?.attributedText = attributedText
}
case 1:
if let todoItem = finished.object(at: index) as? ToDoItem {
let attributedText = NSMutableAttributedString(string: todoItem.name)
attributedText.addAttribute(NSStrikethroughStyleAttributeName, value: 1, range: NSMakeRange(0, attributedText.length))
cell.textLabel?.attributedText = attributedText
}
default:
fatalError("What did you think ??")
}
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
var todoItem: ToDoItem?
switch indexPath.section {
case 0:
todoItem = todos.object(at: UInt(indexPath.row)) as? ToDoItem
case 1:
todoItem = finished.object(at: UInt(indexPath.row)) as? ToDoItem
default:
fatalError("What you think ??")
}
//let realm = RLMRealm.default()
//try! realm.transactionWithBlock() {
//try! realm.beginWriteTransaction()
let realm = try! Realm() // 1
try! realm.write { () -> Void in
todoItem?.finished = !todoItem!.finished
}
//}
tableView.reloadData()
}
func didFinishTypingText(_ typedText: String?) {
if (typedText?.utf16.count)! > 0 {
let newTodoItem = ToDoItem()
newTodoItem.name = typedText!
//let realm = RLMRealm.default()
let realm = try! Realm() // 1
try! realm.write { () -> Void in//
//try! realm.transactionWithBlock() {
//realm.add(newTodoItem)
realm.add(newTodoItem)
//}
}
tableView.reloadData()
}
}
}
答案 0 :(得分:2)
我建议开始的是:
a)将Realm更新到最新版本(撰写本文时为2.0.3),请参阅here。
b)确保您使用的是RealmSwift,而不是Obj-C变体 来自文档:
Realm Objective-C和Realm Swift API不能互操作和使用 他们在一起不受支持。
删除以RLM*
开头的所有Realm对象。
c)而不是try! realm.transactionWithBlock()
使用
try! realm.write {
....
}
d)使用以下方式查询数据库:
realm.objects(ToDoItem.self).filter(predicate)
而不是ToDoItem.objects(with: predicate)