2015-10-16 5 views
8

A volte (raramente ma si verifica) Ho ricevuto l'errore Object has been deleted or invalidated., quando provo a modificare il mio oggetto modello con una proprietà o all'interno di AFnetworking Block. Qualcuno può aiutarmi a trovare quello che sto facendo male?Errore: l'oggetto è stato cancellato o invalidato. (Realm)


Errore - Caso 1:

Codice:

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

Error - Caso 2:

Proprietà:

@property (strong, nonatomic) Model *model; 

Codice:

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

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

Grazie.

risposta

7

Ad esempio 1 la richiesta di rete viene eseguita in modo asincrono su una diversa coda di operazioni e richiama il thread principale, è molto probabile che sia presente del codice, che può essere attivato nel frattempo da un'azione dell'utente ed eliminare il oggetto contemporaneamente. Il riferimento all'oggetto del modello che stai tenendo verrà aggiornato automaticamente e rifletterà la cancellazione. Poiché un oggetto eliminato non può essere modificato, viene segnalato l'errore.

Anche l'esempio 2 implica la concorrenza. Il tuo codice recupera prima l'oggetto del modello, quindi mostra la vista di avviso. Mentre viene mostrato lo UIAlertView, il thread principale non è bloccato. Teoricamente, allo stesso tempo, un'operazione di rete accodata prima potrebbe terminare, il blocco di completamento potrebbe essere inviato, si verifica una cancellazione dell'oggetto modello. L'utente conferma le modifiche. Viene richiamata l'implementazione del delegato, ma si aspetta che l'oggetto recuperato in precedenza sia ancora esistente.

Una possibilità per evitare gli arresti anomali consiste nell'archiviazione di una chiave primaria anziché di un riferimento di modello completo, che manterrebbe l'aggiornamento e riflette le modifiche recenti. La chiave primaria rimarrà costante e dovrebbe essere sempre in grado di identificare il tuo oggetto. È quindi possibile utilizzare la chiave primaria in un secondo momento per recuperare l'oggetto direttamente nella transazione di scrittura.

Si noti che sarà in ogni caso a te definire come si comporta la tua app, se i tuoi dati sono stati modificati contemporaneamente. Puoi provare a ricreare l'oggetto mantenendo più dati in copia o ignorando l'evento e lasciando vincere l'eliminazione o assicurandoti che non si verifichino modifiche in conflitto limitando l'interfaccia in modo adeguato. Devi trovare una strategia di risoluzione dei conflitti.

+0

Invece di inviare il modello che ho modificato per inviare la chiave primaria del modello, e ogni volta che è necessario cerco di trovarlo prima. Crash è andato e funziona correttamente, grazie! –