2015-10-16 2 views
8

Иногда (редко, но происходит) У меня возникла ошибка Object has been deleted or invalidated. при попытке изменить мой объект модели с помощью свойства или внутри AFnetworking Block. Может ли кто-нибудь помочь мне найти то, что я делаю неправильно?Ошибка: объект удален или недействителен. (Realm)


Ошибка - Случай 1:

Код:

- (void)myFunction { 
    Model *model = [Model objectForPrimaryKey:1]; 

    if (model) { 
     [self updateModel:model]; 
    } 
} 

- (void)updateModel:(Model *)model { 

    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; 
    [manager PUT:@"http://www.example.com" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) { 

     [[RLMRealm defaultRealm] beginWriteTransaction]; 
     model.updated = YES; // Crash: Object has been deleted or invalidated. 
     [[RLMRealm defaultRealm] commitWriteTransaction]; 

    } failure:nil]; 
} 

Ошибка - Случай 2:

недвижимости:

@property (strong, nonatomic) Model *model; 

Код:

- (void)myFunction { 
    Model *model = [Model objectForPrimaryKey:1]; 

    if (model) { 
     self.model = model; 

     UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"" message:@"Would you like to edit the model?" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Ok", nil]; 
     [alert show]; 
    } 
} 

UIAlertView Делегат:

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { 
    if (buttonIndex == 1) { 
     [[RLMRealm defaultRealm] beginWriteTransaction]; 
     self.model.updated = YES; // Crash: Object has been deleted or invalidated. 
     [[RLMRealm defaultRealm] commitWriteTransaction]; 
    } 
} 

Спасибо.

ответ

7

Как, например, сетевой запрос выполняется асинхронно в другой очереди операций и обращается к основному потоку, очень вероятно, что у вас есть какой-то код на месте, который может быть запущен между тем действием пользователя и удалением объект одновременно. Ссылка на объект модели, которую вы держите, будет автоматически обновляться и отображать удаление. Поскольку удаленный объект не может быть изменен, он приходит к ошибке.

Также пример 2 включает параллелизм. Сначала код извлекает объект модели, а затем отображает вид предупреждения. Пока отображается UIAlertView, основной поток не блокируется. Теоретически в то же время сетевая операция, установленная в очередь перед завершением, может быть отправлена ​​блок завершения, происходит удаление объекта модели. Пользователь подтверждает изменения. Вызывается реализация делегата, но ожидает, что ранее восстановленный объект все еще будет существовать.

Одна из возможностей избежать сбоев - хранить только первичный ключ, а не полную ссылку на объект модели, которая будет продолжать обновлять и отражать последние изменения. Первичный ключ останется постоянным и всегда сможет идентифицировать ваш объект. Затем вы можете использовать первичный ключ позже для извлечения объекта непосредственно в транзакции записи.

Обратите внимание, что в любом случае вам будет необходимо определить, как ведет себя ваше приложение, если ваши данные были изменены одновременно. Вы можете попытаться воссоздать объект, сохранив больше данных в копии или проигнорировав событие и позвольте удалять выигрыш, или убедитесь, что не будут возникать конфликтующие изменения, ограничив пользовательский интерфейс. Вы должны придумать стратегию разрешения конфликтов.

+0

Вместо отправки модели, которую я изменил, чтобы отправить первичный ключ модели, и каждый раз, когда это необходимо, я пытаюсь найти его раньше. Крушение пропало, и он работает правильно, спасибо! –

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