2015-10-16 19 views
8

ときどき(まれに発生する)モデルオブジェクトをプロパティまたはAFnetworkingブロック内で修正しようとすると、エラーObject has been deleted or invalidated.が発生することがあります。誰かが私が間違っていることを見つけるのを助けることができますか?エラー:オブジェクトが削除または無効化されました。 (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

例1と同様に、ネットワーク要求は別の操作キューで非同期で実行され、メインスレッドにコールバックします。ユーザーアクションによってトリガーされるコードがある可能性が非常に高いです同時にオブジェクト。保持しているモデルオブジェクトの参照は自動的に更新され、削除が反映されます。削除されたオブジェクトは変更できないため、エラーになります。

例2には並行性があります。コードでモデルオブジェクトが最初に取得され、次にアラートビューが表示されます。 UIAlertViewが表示されている間、メインスレッドはブロックされません。理論的には、以前にエンキューされたネットワーク操作が完了すると、完了ブロックがディスパッチされ、モデルオブジェクトの削除が発生します。ユーザーは変更を確認します。デリゲートの実装が呼び出されますが、以前に取得されたオブジェクトがまだ存在することが必要です。

クラッシュを回避する可能性の1つは、完全なモデルオブジェクト参照の代わりにプライマリキーだけを保存することです。最新の変更を反映して反映します。主キーは一定のままで、常にオブジェクトを識別できる必要があります。後で主キーを使用して、書込みトランザクションでオブジェクトを直接取得できます。

データが同時に変更された場合でも、アプリの動作を定義することはどのような場合でも可能です。オブジェクトを再作成しようとすると、より多くのデータをコピーして保持するか、イベントを無視して削除を勝ち取ることができます。また、UIを適切に制限して矛盾する変更が発生しないようにすることもできます。あなたは紛争解決戦略を考え出す必要があります。

+0

モデルを送信するのではなく、Modelプライマリキーを送信するように変更したので、必要になる度に前に見つけようとします。クラッシュがなくなり、正常に動作しています、ありがとう! –

関連する問題