2015-10-16 20 views
8

Czasami (rzadko, ale występuje) Mam błąd Object has been deleted or invalidated., gdy próbuję zmodyfikować mój obiekt modelu z właściwością lub wewnątrz bloku AFnetworking. Czy ktoś może mi pomóc znaleźć to, co robię źle?Błąd: Obiekt został usunięty lub unieważniony. (Realm)


Błąd - Przypadek 1:

Kod:

- (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]; 
} 

Błąd - Przypadek 2:

nieruchomości:

@property (strong, nonatomic) Model *model; 

Kod:

- (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 Delegat:

- (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]; 
    } 
} 

Dzięki.

Odpowiedz

7

Tak jak na przykład 1, żądanie sieciowe jest wykonywane asynchronicznie w innej kolejce operacji i oddzwania do wątku głównego, jest bardzo prawdopodobne, że masz jakiś kod, który może zostać wywołany w międzyczasie przez działanie użytkownika i usunąć obiekt współbieżnie. Referencja modelu obiektu, którą trzymasz, zostanie automatycznie zaktualizowana i odzwierciedli usunięcie. Ponieważ usunięty obiekt nie może być modyfikowany, dochodzi do błędu.

Również przykład 2 dotyczy współbieżności. Twój kod najpierw pobiera obiekt modelu, a następnie pokazuje widok alertu. Po wyświetleniu UIAlertView główny wątek nie jest blokowany. Teoretycznie w tym samym czasie, operacja sieciowa, która może zostać zakończona przed zakończeniem, może zostać wywołany blok zakończenia, następuje usunięcie obiektu modelu. Użytkownik potwierdza zmiany. Twoja implementacja delegata jest wywoływana, ale oczekuje, że poprzednio pobrany obiekt będzie nadal istnieć.

Jedną z możliwości uniknięcia awarii jest przechowywanie tylko klucza podstawowego zamiast pełnego odwołania do obiektu modelu, który będzie aktualizował i odzwierciedlał ostatnie zmiany. Klucz podstawowy pozostanie stały i zawsze powinien być w stanie zidentyfikować twój obiekt. Następnie możesz użyć klucza podstawowego później, aby pobrać obiekt bezpośrednio w transakcji zapisu.

Pamiętaj, że w każdym przypadku zdefiniowanie sposobu działania aplikacji będzie zależało od tego, czy dane zostały zmodyfikowane jednocześnie. Możesz spróbować odtworzyć obiekt, utrzymując więcej danych w kopii wokół lub zignorować zdarzenie i pozwolić, aby usunięcie wygrało, lub upewnić się, że nie wystąpią sprzeczne modyfikacje przez odpowiednie ograniczenie interfejsu użytkownika. Musisz wymyślić strategię rozwiązywania konfliktów.

+0

Zamiast wysłać model I zmieniono, aby wysłać klucz podstawowy modelu i za każdym razem, gdy jest to konieczne, próbuję go znaleźć wcześniej. Awaria zniknęła i działa poprawnie, dziękuję! –

Powiązane problemy