在不提交的情况下更新 RLMObject 的模型
Updating RLMObject's model without committing
本质上,我有一个 UITableView,其中的单元格具有与 RLMObject 中的属性(比方说 10 多个属性)对应的 UITextField。我只允许用户在编辑模式下编辑字段(通过禁用用户交互)。如果用户按下完成,我希望将 RLMObject 提交到数据库。
我已经添加了当 TextField 上的 Editing Did 结束时要触发的操作。该操作应更新 RLMObject 的模型。
我尝试以下操作,其中 self.currentProfile 是我视图的 RLMObject 属性:
- (BOOL) profileTextFieldDidChange:(UITextField *)textField
{
self.currentProfile.name = textField.text; //crashes here
return YES;
}
我的领域对象的 class 如下(为简单起见,我去掉了一些属性):
@interface Profile : RLMObject
@property (nonatomic) NSString * profileId; // primary key
@property (nonatomic) NSString * name;
@property (nonatomic) NSString * color;
-(id) initWithPrimaryKey;
@end
我从上面的代码中得到以下错误消息:
由于未捕获的异常 'RLMException' 而终止应用程序,原因:'Attempting to modify object outside of a write transaction - call beginWriteTransaction on an RLMRealm instance first.'
以前的解决方案指出我应该在更改之前添加 callBeginWriteTransaction 并提交或取消,具体取决于用户是退出并取消编辑还是按下完成并将新配置文件提交到数据库。
我不想在我的 UITableViewController 中添加这些 class 因为我已经解耦了我的程序以具有中间数据访问层。在下面的代码中,我想将所有数据库事务都放在我的 DataAccessServices 层中。有替代解决方案吗?我不是领域专家,而且很新。我想指出,我需要导航到此视图中的另一个视图,并在另一个视图中进行其他领域事务。如果我在切换到新视图时仍在编辑——也就是说我会嵌套 beginWriteTransactions,这会导致问题吗?
提前致谢。
我不满意的当前解决方案如下:
- (void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
if([self.tableView isEditing]){
RLMRealm *realm = [RLMRealm defaultRealm];
[realm cancelWriteTransaction];
}
NSLog(@"gone...");
}
//Edit Mode --------------------------------
- (IBAction)enterEditMode:(id)sender {
if ([self.tableView isEditing]) { //Turn off Edit Mode
[self.tableView setEditing:NO animated:YES];
[self.editButtonItem setTitle:@"Edit"];
[DataAccessServices saveProfile:self.currentProfile];
[self reloadSections];
RLMRealm *realm = [RLMRealm defaultRealm];
[realm commitWriteTransaction];
}
else {// Turn on edit mode
[self.editButtonItem setTitle:@"Done"];
[self.tableView setEditing:YES animated:YES];
[self reloadSections];
RLMRealm *realm = [RLMRealm defaultRealm];
[realm beginWriteTransaction];
}
}
据我了解,您正在尝试更新现有记录的数据。
根据 docs,您可以使用现有记录的主键初始化一个新对象,如下所示。
Profile *myWriteableProfile = [[Profile alloc] initWithValue:self.currentProfile];
myWriteableProfile.name = @"Dummy Name!"; // No Exception will be thrown! :)
RLMRealm *realm = [RLMRealm defaultRealm];
[realm beginWriteTransaction];
[Profile createOrUpdateInRealm:realm withValue:myWriteableProfile];
[realm commitWriteTransaction];
希望对您有所帮助:)
本质上,我有一个 UITableView,其中的单元格具有与 RLMObject 中的属性(比方说 10 多个属性)对应的 UITextField。我只允许用户在编辑模式下编辑字段(通过禁用用户交互)。如果用户按下完成,我希望将 RLMObject 提交到数据库。
我已经添加了当 TextField 上的 Editing Did 结束时要触发的操作。该操作应更新 RLMObject 的模型。
我尝试以下操作,其中 self.currentProfile 是我视图的 RLMObject 属性:
- (BOOL) profileTextFieldDidChange:(UITextField *)textField
{
self.currentProfile.name = textField.text; //crashes here
return YES;
}
我的领域对象的 class 如下(为简单起见,我去掉了一些属性):
@interface Profile : RLMObject
@property (nonatomic) NSString * profileId; // primary key
@property (nonatomic) NSString * name;
@property (nonatomic) NSString * color;
-(id) initWithPrimaryKey;
@end
我从上面的代码中得到以下错误消息: 由于未捕获的异常 'RLMException' 而终止应用程序,原因:'Attempting to modify object outside of a write transaction - call beginWriteTransaction on an RLMRealm instance first.'
以前的解决方案指出我应该在更改之前添加 callBeginWriteTransaction 并提交或取消,具体取决于用户是退出并取消编辑还是按下完成并将新配置文件提交到数据库。
我不想在我的 UITableViewController 中添加这些 class 因为我已经解耦了我的程序以具有中间数据访问层。在下面的代码中,我想将所有数据库事务都放在我的 DataAccessServices 层中。有替代解决方案吗?我不是领域专家,而且很新。我想指出,我需要导航到此视图中的另一个视图,并在另一个视图中进行其他领域事务。如果我在切换到新视图时仍在编辑——也就是说我会嵌套 beginWriteTransactions,这会导致问题吗?
提前致谢。
我不满意的当前解决方案如下:
- (void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
if([self.tableView isEditing]){
RLMRealm *realm = [RLMRealm defaultRealm];
[realm cancelWriteTransaction];
}
NSLog(@"gone...");
}
//Edit Mode --------------------------------
- (IBAction)enterEditMode:(id)sender {
if ([self.tableView isEditing]) { //Turn off Edit Mode
[self.tableView setEditing:NO animated:YES];
[self.editButtonItem setTitle:@"Edit"];
[DataAccessServices saveProfile:self.currentProfile];
[self reloadSections];
RLMRealm *realm = [RLMRealm defaultRealm];
[realm commitWriteTransaction];
}
else {// Turn on edit mode
[self.editButtonItem setTitle:@"Done"];
[self.tableView setEditing:YES animated:YES];
[self reloadSections];
RLMRealm *realm = [RLMRealm defaultRealm];
[realm beginWriteTransaction];
}
}
据我了解,您正在尝试更新现有记录的数据。 根据 docs,您可以使用现有记录的主键初始化一个新对象,如下所示。
Profile *myWriteableProfile = [[Profile alloc] initWithValue:self.currentProfile];
myWriteableProfile.name = @"Dummy Name!"; // No Exception will be thrown! :)
RLMRealm *realm = [RLMRealm defaultRealm];
[realm beginWriteTransaction];
[Profile createOrUpdateInRealm:realm withValue:myWriteableProfile];
[realm commitWriteTransaction];
希望对您有所帮助:)