gpt4 book ai didi

ios - Core Data 多项编辑效率与随机误差

转载 作者:行者123 更新时间:2023-11-29 13:21:08 27 4
gpt4 key购买 nike

我希望这不是一个重复的问题。我似乎找不到任何类似的东西。大多数核心数据问题似乎与新对象创建有关...

我有一个包含大约 23,000 个项目的数据库的程序。我正在尝试创建导出/导入功能以将数据发送到其他设备(未与 iCloud 链接)。

导出工作正常,电子邮件也是如此......

我有导入功能,但运行缓慢(稍后会详细介绍,似乎不能很好地与 iPhone 5 或 iPad 3 配合使用)

我有一个函数可以解析我导入到 NSArray (_importedRows) 中的数据,然后我运行以下代码:

self.managedObjectContext = [(AppDelegate*)[[UIApplication sharedApplication] delegate] managedObjectContext];

NSManagedObjectContext *ctx = self.managedObjectContext;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:@"CHECKLIST"
inManagedObjectContext:ctx];
[fetchRequest setEntity:entity];
ImportedData *importedData;
NSString *verify;
NSError *error = nil;
NSManagedObject *updatedObject;
NSArray *matchingItems;
for (int i = 0; i < [_importedRows count]; i++) {
importedData = [_importedRows objectAtIndex:i];
verify = importedData.uniqueID;
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"uniqueID == %@", verify]];
[fetchRequest setFetchLimit:1];
matchingItems = [ctx executeFetchRequest:fetchRequest error:&error];

for (updatedObject in matchingItems) {
HUD.detailsLabelText = [NSString stringWithFormat:@"Updating %@" , [updatedObject valueForKey:@"figureName"]];
[updatedObject setValue:importedData.numberOwned forKey:@"numberOwned"];
[updatedObject setValue:importedData.numberWanted forKey:@"wishList"];
[updatedObject setValue:importedData.availableTrade forKey:@"tradeList"];

}

[ctx save:&error];

if (error != nil) {
NSLog(@"error saving managed object context: %@", error);
}

}

基本上,我正在获取一个核心数据实体,然后遍历我的数组以检查匹配项。当我找到匹配项(uniqueID 谓词)时,我将使用导入的数据更新对象。这段代码在我的 iPhone 4s 上运行良好,但速度很慢。 4,000 个项目大约需要 4-5 分钟。我做错了什么吗?我应该更频繁地调用保存功能吗?

作为奖励,出于某种原因,当我在 iPhone 5 上测试这段代码时,它几乎无法正常工作。10 次中有 9 次(在我的 iPad 3 上有 50% 的时间)我得到了

“1 月 14 日 08:06:44:* 由于未捕获的异常‘NSInvalidArgumentException’而终止应用程序,原因:‘-[__NSCFSet addObject:]:尝试插入 nil’”

在控制台中。想法?

如果需要更多详细信息,请告诉我!

更新:似乎 handleOpenURL 被调用了两次......一次在 applicationdidfinishlaunching
NSURL *url = (NSURL *)[launchOptions valueForKey:UIApplicationLaunchOptionsURLKey];
如果 (url != nil && [url isFileURL]) {
[self.window.rootViewController performSelector:@selector(showWithLabel:) withObject:url afterDelay:6];
}

一旦来到这里:

-(BOOL) application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation

{ if (url != nil && [url isFileURL]) { [self.window.rootViewController performSelector:@selector(showWithLabel:) withObject:url]; } return YES; }

我必须将它们都放在应用程序委托(delegate)中,否则该函数不会总是被调用(一次用于应用程序启动时,一次用于应用程序已经在后台,我相信)- 我'我们添加了一个检查以防止它在 showWithLabel 线程中第二次启动,但它似乎不是一个非常优雅的解决方案......

更新:@mundi 建议清理 fetchedresults 代码如下:

NSArray *importedIDs = [_importedRows valueForKeyPath:@"uniqueID"];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
fetchRequest.entity = [NSEntityDescription entityForName:@"CHECKLIST"
inManagedObjectContext:ctx];
fetchRequest.predicate = [NSPredicate predicateWithFormat:
@"uniqueID in %@", importedIDs];

NSError *error = nil;
NSManagedObject *updatedObject;
NSArray *matchingItems;
matchingItems = [ctx executeFetchRequest:fetchRequest error:&error];
ImportedData *importedData;
for (int i = 0; i < [_importedRows count]; i++) {
importedData = [_importedRows objectAtIndex:i];
for (updatedObject in matchingItems) {
if ([importedData.uniqueID isEqualToString:[updatedObject valueForKey:@"uniqueID"]]) {
HUD.detailsLabelText = [NSString stringWithFormat:@"Updating %@" , [updatedObject valueForKey:@"figureName"]];
[updatedObject setValue:importedData.numberOwned forKey:@"numberOwned"];
[updatedObject setValue:importedData.numberWanted forKey:@"wishList"];
[updatedObject setValue:importedData.availableTrade forKey:@"tradeList"];
}


}
}


[ctx save:&error];

我确信它仍然可以更清晰一些,并且实际更新部分(除了将 fetchedresults 中的每个项目与初始数组中的每个项目进行比较以确保它们已更新之外,我不确定该怎么做正确,但组合的 fetchedresults 极大地提高了速度(最初 4000 项需要 240 秒,现在在 80-120 秒之间)

首先对数组进行排序,然后按顺序更新,这再次极大地加快了速度:

NSArray *matchingItemsSorted;
matchingItemsSorted = [matchingItems sortedArrayUsingComparator:^NSComparisonResult(id a, id b) {
NSString *first = [a valueForKey:@"uniqueID"];
NSString *second = [b valueForKey:@"uniqueID"];
return [first caseInsensitiveCompare:second];
}];


NSArray *importedRowsSorted;
importedRowsSorted = [_importedRows sortedArrayUsingComparator:^NSComparisonResult(id a, id b) {
NSString *first = [a valueForKeyPath:@"uniqueID"];
NSString *second = [b valueForKeyPath:@"uniqueID"];
return [first caseInsensitiveCompare:second];
}];

int i = 0;
for (updatedObject in matchingItemsSorted) {
NSLog(@"do we match? %@ : %@", [[importedRowsSorted objectAtIndex:i] valueForKeyPath:@"uniqueID"], [updatedObject valueForKey:@"uniqueID"]);
HUD.detailsLabelText = [NSString stringWithFormat:@"Updating %@" , [updatedObject valueForKey:@"figureName"]];
[updatedObject setValue:[[importedRowsSorted objectAtIndex:i] valueForKeyPath:@"numberOwned"] forKey:@"numberOwned"];
[updatedObject setValue:[[importedRowsSorted objectAtIndex:i] valueForKeyPath:@"numberWanted"] forKey:@"wishList"];
[updatedObject setValue:[[importedRowsSorted objectAtIndex:i] valueForKeyPath:@"availableTrade"] forKey:@"tradeList"];
i++;


}

4000 strip 有 nslog 的项目需要 13 秒左右……现在唯一奇怪的是,当我注释掉 nslog 时,它经常崩溃……它发生得如此之快以至于破坏了核心数据——当它没有发生时'崩溃,只需要大约 4 秒?

谢谢,扎克

最佳答案

你有两个嵌套循环。使用此模式可以加快速度:

NSArray *importedIDs = [_importedRows valueForKeyPath:@"uniqueID"];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
fetchRequest.entity = [NSEntityDescription entityForName:@"CHECKLIST"
inManagedObjectContext:ctx];
fetchRequest.predicate = [NSPredicate predicateWithFormat:
@"uniqueID in %@", importedIDs];

像这样,您可以获取一个包含所有匹配项的数组。

关于ios - Core Data 多项编辑效率与随机误差,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14319132/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com