2015-10-16 93 views
8

有時(很少發生但是發生)當試圖用屬性或AFnetworking Block內部修改我的模型對象時,出現錯誤Object has been deleted or invalidated.。任何人都可以幫助我找到我做錯了什麼嗎?錯誤:對象已被刪除或無效。 (領域)


錯誤 - 案例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時,主線程未被阻止。從理論上講,以前排隊的網絡操作可能會完成,可以調度完成塊,刪除模型對象。用戶確認修改。您調用了委託的實現,但期望以前檢索的對象仍然存在。

避免崩潰的一種可能性是僅存儲主鍵而不是完整的模型對象引用,該引用將不斷更新和反映最近的更改。主鍵將保持不變,並應始終能夠識別您的對象。然後,您可以稍後使用主鍵在您的寫入事務中直接檢索對象。

請注意,如果您的數據被同時修改,它將在任何情況下由您來定義您的應用的行爲。您可以嘗試重新創建對象,通過保留更多數據進行復制,或忽略事件並讓刪除成功,或通過充分限制用戶界面來確保不會發生衝突修改。你必須想出解決衝突的策略。

+0

而不是發送模型我改變發送模型的主鍵,每次有必要我試着找到它之前。崩潰消失了,它的工作正常,謝謝! –