2015-03-19 5 views

ответ

4

Адрес the documentation on updating objects in Realm.

И вот еще один вариант для обновления объектов, чем тот, который обсуждался в других ответах.

Много раз, когда я хочу обновлять объекты, мне действительно нужно обновлять один или два свойства, одна досадная вещь о Realm - это изменение свойств сохраняемого объекта, которое должно быть завернуто в транзакцию записи, поэтому я как правило, добавить метод обертку к своим объектам, чтобы очистить интерфейс немного:

@implementation SomeRealmClass 

    - (void)update:(void (^)(SomeRealmClass *instance))updateBlock 
    { 
     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ 
      RLMRealm *realm = [RLMRealm defaultRealm]; 
      [realm beginWriteTransaction]; 
      updateBlock(self); 
      [realm commitWriteTransaction]; 

     }); 
    } 

@end 

таким образом, я могу обновить объект следующим образом:

SomeRealmClass *instance = [[SomeRealmClass allObjects] objectAtIndex:0]; 

[instance update:^(SomeRealmClass *instance) { 
    instance.foo = @"foo 2"; 
    instance.bar = @"bar 2"; 
}]; 
+0

На самом деле это не сработает, так как вы модифицируете экземпляр 'RLMObject' в неправильном потоке – segiddins

+1

@segiddins. Вы правы, я изучал Королевство, и это изначально казалось, что оно работает, но в итоге не получилось.К сожалению, я закончил тем, что не использовал Realm в проекте, и поэтому я никогда не беспокоился о том, как лучше всего исправить эту конкретную проблему с потоками. Мне было бы здорово, если бы вы могли предоставить некоторые отзывы о лучшем способе сделать это для потомков – Jaymon

4

Вы можете использовать следующий API из класса RLMRealm:

– addOrUpdateObject: 
– addOrUpdateObjectsFromArray: 

https://realm.io/docs/objc/latest/api/Classes/RLMRealm.html#//api/name/addOrUpdateObject: https://realm.io/docs/objc/latest/api/Classes/RLMRealm.html#//api/name/addOrUpdateObjectsFromArray:

Для обновления объектов в Realm, вам необходимо определить некоторые первичный ключ в вашем RLMObject подклассов, так что Realm тогда знает, что обновлять.

+ (NSString *) primaryKey 
{ 
    return @"somePropertyNameAsString"; 
} 
+0

По какой-то причине, когда я пытаюсь обновить объект он бросает мне исключение, говоря, что он не может найти первичный ключ. Я проверил, и мой первичный ключ равен «nil». Должен ли 'PrimaryKey' быть свойством в классе RLMObject? – mlevi

+0

См. Обновленное описание выше. – gagarwal

+0

Awesome - thanks :) – mlevi

2

В Realm, всякий раз, когда вы извлекаете объект из базы данных, вы можете обновлять его свойства, и эти изменения будут отражены в базе данных.

+1

Есть ли какие-либо предварительные условия для этого (т. Е. Свойство, помеченное как «динамическое» и т. Д.)? Пробовал это, но обновления, похоже, не сохраняются, даже если они находятся в блоке транзакций записи. – Marchy

-1

Вот метод, который я написал, чтобы обновить мой которая имеет таблицу под названием CDlevels.

Вы можете вызвать этот метод из любого потока, поскольку он выделит область из этого потока и сделает это нужным.

-(void)updateLevel:(int)levelNo WithScore:(NSString*)strScore complete:(void (^)(BOOL))completed{ 

RLMRealm *realm = [RLMRealm defaultRealm]; 

NSPredicate *pred = [NSPredicate predicateWithFormat:@"levelNo = %d",levelNo]; 

RLMResults *RLMLevels = [CDLevels objectsWithPredicate:pred]; 

CDLevels *myLevel = [[CDLevels alloc]init]; 

myLevel = [RLMLevels objectAtIndex:0]; 

[realm beginWriteTransaction]; 
myLevel.score = strScore; 
[realm commitWriteTransaction]; 

completed(YES); 

} 

Это, как вы можете вызвать этот метод, скажем, для обновления уровня 1 со счетом 100

[self updateLevel:1 WithScore:@"100" complete:^(BOOL completed) { 

     if (completed) { 
      NSLog(@"score updated"); 
     } 

    }]; 

Я попробовал это, и это работает очень здорово. Я пытаюсь изменить одно из моих приложений coredata в Realm.

Надеюсь, что эта помощь. Если ответ помечен как ответ неправильный, исправьте его.

Это примитивный метод, и я считаю, что его можно улучшить.

веселит

Смежные вопросы