在使用 CoreData 更新对象后立即获取数据时遇到以下问题。
以下是我遇到的问题的一些细节:
- 我有一个“PersonDetailsViewController”,其中有 2 个 TableView ,其中包含一些关于一个人的信息(每个 Person 对象都被添加到 CoreData 上下文中,并包含一个名字和一组电子邮件)。
- tablewiews 的每一行都是可点击的,并连接到一个模态 VC(“EditDetailsVC”),让用户更新此人的信息。
- 在通过 CoreData 上下文中的托管对象更新信息后,在“EditDetailsVC”上点击“完成”返回到“PersonDetailsVC”。
- 在“PersonsDetailsVC”的
viewDidLoadviewWillAppear 中,我取回此人的信息并填充表格 View 。
在最后一步,事情没有以正确的方式发生:有时从数据库中正确检索了 Person 对象,有时什么也没有获取。
我尝试在更新对象后立即保存上下文或不保存上下文,但同样的问题发生了。
我假设这与访问数据库的时间有关,并且当我尝试在上下文中获取一些数据时,数据可能正在写入上下文?
你能帮帮我吗?
编辑:
以下所有内容都属于一个名为“DataManager”的类,该类集中了所有 CoreData 访问。 该类使用单例设计模式。
@property (nonatomic,strong) NSManagedObjectContext * context ;
#define DM_CONTEXT [DataManager sharedInstance].context;
这是在 viewWillAppear 中调用的方法:
+(NSDictionary*) getTargetDetailsForIdentifier:(NSNumber*)identifier
{
NSMutableDictionary * targetDetails ;
NSFetchRequest * request = [NSFetchRequest fetchRequestWithEntityName:@"Target"];
NSPredicate * predicate = [NSPredicate predicateWithFormat:@"identifier =%@",identifier];
request.predicate = predicate ;
NSError * err ;
NSArray * result = [DM_CONTEXT executeFetchRequest:request error:&err];
if(err)
{
NSLog(@"%s : Error when fetching target details for the identifier <%@>",__PRETTY_FUNCTION__,identifier);
}
else if(![result count])
{
NSLog(@"%s : Nothing found for the identifier <%@>",__PRETTY_FUNCTION__,identifier);
}
else if([result count] > 1)
{
NSLog(@"%s : Error more than 1 target corresponding to the identifier <%@>",__PRETTY_FUNCTION__,identifier);
}
else
{
NSLog(@"%s : Target details successfully fetched for identifier <%@>",__PRETTY_FUNCTION__,identifier);
targetDetails = [[NSMutableDictionary alloc] init];
Target * target = [result lastObject];
[targetDetails setObject:target.firstname forKey:FIRSTNAME_KEY];
[targetDetails setObject:target.lastname forKey:LASTNAME_KEY];
[targetDetails setObject:target.rank forKey:RANK_KEY];
[targetDetails setObject:target.identifier forKey:IDENTIFIER_KEY];
if(target.photoData)
{
[targetDetails setObject:target.photoData forKey:PHOTODATA_KEY];
}
NSSet * emailSet = [[NSSet alloc] initWithSet:target.emailList];
NSSet * phoneSet = [[NSSet alloc] initWithSet:target.phoneList];
[targetDetails setObject:emailSet forKey:EMAILS_KEY];
[targetDetails setObject:phoneSet forKey:PHONES_KEY];
}
return targetDetails ;
}
这是更新方法的片段。在这里,我只展示更新用唯一编号标识的人的电子邮件地址的部分:
+(void) replaceObject:(id)object withObject:(id)newObject forKey:(NSString*)key forIdentifier:(NSNumber*)identifier
{
if([key isEqualToString:EMAIL_KEY])
{
if([object isKindOfClass:[NSString class]] && [newObject isKindOfClass:[NSString class]])
{
NSString * email = (NSString *)object;
NSString * newEmail = (NSString *)newObject;
NSFetchRequest * request = [NSFetchRequest fetchRequestWithEntityName:@"Email"];
NSPredicate * predicate = [NSPredicate predicateWithFormat:@"(email =%@) AND (emailOwner.identifier=%@)",email,identifier];
request.predicate = predicate ;
NSError * err ;
NSArray * result = [DM_CONTEXT executeFetchRequest:request error:&err];
if(err)
{
NSLog(@"%s : Error when fetching the email object to be removed for target identifier <%@>",__PRETTY_FUNCTION__,identifier);
}
else if(![result count])
{
NSLog(@"%s : Nothing found.",__PRETTY_FUNCTION__);
}
else if([result count] > 1)
{
NSLog(@"%s : Error. More than 1 email object fetched for target identifier <%@>",__PRETTY_FUNCTION__,identifier);
}
else
{
Email * emailToUpdate = [result lastObject];
emailToUpdate.email = newEmail ;
if (![DM_CONTEXT save:nil])
{
NSLog(@"%s : Can't Save after updating email! for the identifier <%@>",__PRETTY_FUNCTION__,identifier);
}
else
{
NSLog(@"%s : Email successfully updated.",__PRETTY_FUNCTION__);
}
}
}
else
{
NSLog(@"%s : Nothing to replace, or bad objects.",__PRETTY_FUNCTION__);
}
}
}
问题是每隔一段时间,在我更新此人的信息后,当我返回 viewWillAppear
时,getTargetDetailsForIdentifier:
不会返回任何内容(结果数组是空)。
最佳答案
returns to the "PersonDetailsVC" ... In the "PersonsDetailsVC" 's viewDidLoad, I fetch back the person's info and populate the tableviews.
好吧,但这没有意义。 viewDidLoad
在 View Controller 的生命周期中仅被调用一次。当您从模态视图 Controller 返回时,您不能使用它来“取回此人的信息”;它甚至没有被调用。
您应该在 viewWillAppear
或 viewDidAppear
中完成此类工作。
如果 viewDidLoad
在您从模态视图 Controller 返回时被调用,那么您的架构也有问题,即您不是在“返回”而是在创建一个全新的 View Controller ,这也是错误的。
关于iOS 核心数据 - 编辑对象后不会立即获取任何内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16022504/