Object has been deleted or invalidated.当尝试使用属性或AFnetworking Block内部修改模型对象时,有时(很少会发生)我收到错误.任何人都可以帮我找到我做错的事吗?
错误 - 案例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];
}
Run Code Online (Sandbox Code Playgroud)
错误 - 案例2:
属性:
@property (strong, nonatomic) Model *model;
Run Code Online (Sandbox Code Playgroud)
码:
- (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];
}
}
Run Code Online (Sandbox Code Playgroud)
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];
}
}
Run Code Online (Sandbox Code Playgroud)
谢谢.
对于示例1,网络请求在不同的操作队列上异步执行并回调到主线程,很可能您有一些代码,可以通过用户操作同时触发并同时删除对象.您持有的模型对象引用将自动更新并反映删除.由于无法修改已删除的对象,因此会出现错误.
示例2还涉及并发性.您的代码首先检索模型对象,然后显示警报视图.虽然UIAlertView被示出,主线程没有被阻塞.理论上,同时排队的网络操作可以完成,可以调度完成块,发生模型对象的删除.用户确认修改.调用您的委托实现,但希望先前检索的对象仍然存在.
避免崩溃的一种可能性是仅存储主键而不是完整模型对象引用,这将不断更新并反映最近的更改.主键将保持不变,并始终能够识别您的对象.然后,您可以稍后使用主键直接在写入事务中检索对象.
请注意,如果您的数据同时修改,那么在任何情况下都可以定义您的应用的行为方式.您可以尝试重新创建对象,通过在副本中保留更多数据,或忽略事件并让删除获胜,或通过充分限制UI来确保不会发生冲突的修改.你必须提出一个冲突解决策略.
| 归档时间: |
|
| 查看次数: |
2126 次 |
| 最近记录: |