写事务中的域 - 首先在RLMRealm实例上调用beginWriteTransaction

时间:2016-11-07 07:57:09

标签: uitableview swift3 realm ios10

我的应用因未捕获的异常而终止:

  

' 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()
    }
}
}

1 个答案:

答案 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)