2017-06-05 66 views
0

这是我Realm对象:关于在境界数据库事务

class AchievementDate : Object { 

    dynamic var date: Date = Date() 
    dynamic var apple: Int = Int(0) 

    func save() { 
     do { 
      let realm = try Realm() 
      try realm.write { 
       realm.add(self) 
      } 
     } catch let error as NSError { 
      fatalError(error.localizedDescription) 
     } 
    } 
} 

我改变视图控制器的viewDidLoad()方法苹果公司的价值,因为你可以看到:

override func viewDidLoad() {  
    super.viewDidLoad() 
    achievementDate.apple = 2 
    achievementDate.save()  
} 

然后我更新了苹果的价值时,用户点击屏幕上的暂停按钮,如下所示:

@IBAction func pausedButtonTapped(_ sender: UIButton) { 
    achievementDate.apple += 1 
    achievementDate.save() 
} 

Xcode成功运行它,但是当我点击暂停按钮时,应用程序崩溃。在控制台,它说:

***终止应用程序由于未捕获的异常“RLMException”,原因:“试图修改对象的写事务之外 - 先请一个RLMRealm实例 beginWriteTransaction”

我对此很困惑,顺便说一句,交易意味着什么?非常感谢。

回答

2

写入事务用于将Realm中对象的修改分组为单个工作单元。 Managed Realm对象只能在写入事务中修改。写入交易的范围是您传递给Realm.write(_:)的呼叫的块。对write的调用开始写入事务,主体在事务处于活动状态时执行,并且当该块返回写入事务被提交并且更改持久化到Realm文件时。

您还没有分享如何初始化achievementDate,但基于您看到的是一个AchievementDate实例是一个托管对象(即,它已创建,然后添加到一个领域,或者它是从一个领域加载的)。作为例外说明,您只能修改写入事务中的托管对象。您可以扩大写入事务的范围以包含修改受管理对象,也可以完全避免修改受管理对象(通过将主键添加到模型类中,并使用Realm.create(_:value:update:)Realm.add(_:update:)update: true来更新具有给定主键值的现有对象)。

+0

我通过声明一个变量来初始化对象:var achievementDate = AchievementDate()然后将它传递给View Controller。 – Nan

+0

顺便说一句,如何扩大写交易的范围以包含修改,如何解决这个问题?提前致谢。 – Nan

+0

这意味着它作为一个非托管对象开始生活,但是在您第一次调用'realm.add(self,update:true)'(在'viewDidLoad()'内)时就会被管理。要扩大写入事务的范围,您需要将调用从'save()'函数移出'Realm.write(_ :)'。 – bdash

1

首先,你需要定义一个主键如果要更新模型:

class AchievementDate: Object { 
    dynamic var id = 0 
    dynamic var date:Date = Date() 
    dynamic var apple:Int = Int(0) 

    override static func primaryKey() -> String? { 
     return "id" 
    } 
} 

然后更新与示范:

static func save(achievementDate:AchievementDate) { 
    let realm = try! Realm() 
    try! realm.write { 
     realm.add(achievementDate, update: true) 
    } 
} 

或者,如果你不不想要主键,并且已经从Realm中检索模型,则可以像这样更新模型:

let realm = try! Realm() 
try! realm.write { 
    achievementDate.apple = 2 
} 
+0

您不需要定义主键来更新对象。您可以通过任何支持的查询检索对象的引用,然后在写入事务中修改其属性。 – bdash

+0

@bdash如果我定义一个主键来更新对象,我能理解主键实际上是这个对象在内存中的引用吗?然后检索并更新 – Nan

+0

主键(如果声明的话)是唯一标识给定对象的对象上的属性。Realm提供了一些便利函数,可用于声明主键的类(['Realm.object(ofType:forPrimaryKey:)'](https://realm.io/docs/swift/latest/api/Classes/Realm .html#/ s:FC10RealmSwift5Realm6objectu0_RxCS_6ObjectrFT6ofTypeMx13forPrimaryKeyq__GSqx_)和'Realm.create(_:value:update:)'/'Realm.add(_:update:)'''update':''。 – bdash