2015-10-16 97 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

而不是发送模型我改变发送模型的主键,每次有必要我试着找到它之前。崩溃消失了,它的工作正常,谢谢! –