我第一次使用Core Data,以斯坦福iOS应用程序开发课程为指导。我几乎从演示应用程序中复制了代码(当然我根据我的需要调整了它),但我目前遇到两个问题。
我的应用程序是一个地图视图,只需点击一个按钮即可显示模态视图控制器。此模态视图检查是否创建了UIManagedDocument
。如果没有,它会创建一个并插入数据。这些数据来自一个属性列表(258项,所以没有太多过分)。如果它已经创建(通过先前显示该视图),如果我的逻辑成立,则可以安全地假设它也具有内容,因为NSManagedObject
是在创建文档的同时创建的。第一次运行完全正常,表加载,我的所有数据都正确显示。
然而,当我解雇然后重新显示我的模态视图时,该表保持为空。我正在检查文档的状态,即UIDocumentStateNormal
,因此查询它应该没问题。但它不是:我的fetchedResultsController返回0行。如果我正确理解UIManagedContext
,我遇到的行为可能是由错误/不同的上下文引起的,但我确保:1)我将文档(不仅仅是上下文)传递给{中的模态视图{1}},2)当模态视图被解除时,我将带有上下文的文档传递回呈现视图。这就是为什么我认为它可能不是上下文,而是其他东西。
另一件事:在首次启动应用时插入258条记录在模拟器中足够快。但是,在我的手机上可能需要整整13秒。插入代码如下所示(为便于阅读而修改):
prepareForSegue:sender
要明确:这段代码运行得很好,但它确实很慢。它被封装在一个被称为258次的方法中。 + (Department *)departmentName:(NSString *)name
withAttributes:(NSDictionary *)attributes
inContext:(NSManagedObjectContext *)context {
Department *department = [NSEntityDescription insertNewObjectForEntityForName:@"Department" inManagedObjectContext:context];
department.name = name;
NSArray *informationElements = [attributes objectForKey:@"information"];
for (int i = 0; i < [informationElements count]; i++) {
NSString *informationValue = [[informationElements objectAtIndex:i] objectForKey:@"value"];
if ([[[informationElements objectAtIndex:i] objectForKey:@"description"] isEqualToString:@"phone"]) {
department.phone = informationValue;
} else if ([[[informationElements objectAtIndex:i] objectForKey:@"description"] isEqualToString:@"email"]) {
department.email = informationValue;
} else if ([[[informationElements objectAtIndex:i] objectForKey:@"description"] isEqualToString:@"web"]) {
department.website = informationValue;
}
}
return department;
}
最多包含三个元素,这意味着最多有258 * 3 = 774个循环。实际上它远不如此,但即使它是774,也不应该花13秒,对吗?
下面的代码段显示了informationElements
的初始化:
UIManagedDocument
if (![[NSFileManager defaultManager] fileExistsAtPath:[self.database.fileURL path]]) {
[self.database saveToURL:self.database.fileURL forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) {
[self setupFetchedResultsController];
[self fetchDepartmentsIntoDocument:self.database];
}];
} else if (self.database.documentState == UIDocumentStateClosed) {
[self.database openWithCompletionHandler:^(BOOL success) {
[self setupFetchedResultsController];
}];
} else if (self.database.documentState == UIDocumentStateNormal) {
[self setupFetchedResultsController];
}
读取属性列表,然后运行一个循环,为每个属性列表项调用fetchDepartmentsIntoDocument
。
如果有人能给我一些帮助,我们将不胜感激!
答案 0 :(得分:1)
对于速度问题,我会研究使用谓词;这应该可以加快速度!
谓词使得上下文仅根据您选择的条件返回所需的值。它们更快的原因是因为它不必将每个存储的实体对象转换为托管对象,而是可以直接从属性中提取,从而大大加快了比较。
答案 1 :(得分:0)
当您将Department对象插入上下文时,是否为每个对象保存?插入相对便宜,但保存(即-[NSManagedobjectContext save:]
)是昂贵的(因为数据库必须执行锁定和文件I / O)。
另外,在风格上更有说服力,你可以做到
for (NSDictionary *element in informationElements) {
NSString *informationValue = [element objectForKey:@"value"];
if ([[element objectForKey:@"description"] isEqualToString:@"phone"]) {
department.phone = informationValue;
} else if ([[element objectForKey:@"description"] isEqualToString:@"email"]) {
department.email = informationValue;
} else if ([[element objectForKey:@"description"] isEqualToString:@"web"]) {
department.website = informationValue;
}
}
遍历你的词典数组。