Iphone 核心数据导入失败
我正在尝试将一个大型数据集(~6000)导入到我的核心数据应用程序中。我已经阅读了苹果的文档“高效导入数据”,我认为我的设置是正确的。奇怪的是,应用程序没有在模拟器中崩溃,虽然如果我使用泄漏工具运行它会崩溃,但它没有保存所有数据。有时它只能保存300-400个数据集,而有时它会保存3000-4000个数据集,很少保存整个数据集。我认为这可能与内存泄漏有关,而且我对使用NSAutoReleasePool还很陌生,任何帮助都将不胜感激Iphone 核心数据导入失败,iphone,objective-c,core-data,memory-leaks,Iphone,Objective C,Core Data,Memory Leaks,我正在尝试将一个大型数据集(~6000)导入到我的核心数据应用程序中。我已经阅读了苹果的文档“高效导入数据”,我认为我的设置是正确的。奇怪的是,应用程序没有在模拟器中崩溃,虽然如果我使用泄漏工具运行它会崩溃,但它没有保存所有数据。有时它只能保存300-400个数据集,而有时它会保存3000-4000个数据集,很少保存整个数据集。我认为这可能与内存泄漏有关,而且我对使用NSAutoReleasePool还很陌生,任何帮助都将不胜感激 NSURL *url = [NSURL URLWithS
NSURL *url = [NSURL URLWithString:@""];
NSString *responseString = [NSString stringWithContentsOfURL:url encoding:NSASCIIStringEncoding error:nil];
if (responseString) {
NSArray *players = [responseString componentsSeparatedByString:@";"];
NSUInteger LOOP_LIMIT = 100, count = 0;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSManagedObjectContext *context = [[AppController sharedAppController] managedObjectContext];
[context setUndoManager:nil];
for (int i=0; i<([players count] - 1); i++) {
NSArray *info = [[players objectAtIndex:i] componentsSeparatedByString:@","];
NSString *dateInfo = [info objectAtIndex:10];
NSLocale *usLocale = [[[NSLocale alloc] initWithLocaleIdentifier:@"en_US"] autorelease];
NSDateFormatter *fo = [[[NSDateFormatter alloc] init] autorelease];
[fo setDateFormat:@"MM/dd/yyyy"];
[fo setLocale:usLocale];
[fo setTimeZone:[NSTimeZone systemTimeZone]];
NSDate *dob = [fo dateFromString:dateInfo];
Players *player = [NSEntityDescription insertNewObjectForEntityForName:@"Players"
inManagedObjectContext:context];
NSNumberFormatter *f = [[[NSNumberFormatter alloc] init] autorelease];
[f setNumberStyle:NSNumberFormatterNoStyle];
player.playerID = [f numberFromString:[info objectAtIndex:0]];
player.lastName = [info objectAtIndex:1];
player.firstName = [info objectAtIndex:2];
player.position = [info objectAtIndex:4];
NSString *teamName = [info objectAtIndex:3];
NSFetchRequest *req = [[[NSFetchRequest alloc] init] autorelease];
NSEntityDescription *ent = [NSEntityDescription entityForName:@"Teams" inManagedObjectContext:context];
[req setEntity:ent];
[req setIncludesPropertyValues:NO];
NSPredicate *pre = [NSPredicate predicateWithFormat:@"team=%@", teamName];
[req setPredicate:pre];
NSArray *list = [context executeFetchRequest:req error:nil];
if ([list count]) {
Teams *team = [list objectAtIndex:0];
player.team_Players_Teams = team;
}
count++;
if (count == LOOP_LIMIT) {
[context save:nil];
[context reset];
[pool drain];
pool = [[NSAutoreleasePool alloc] init];
count = 0;
}
}
if (count != 0) {
NSLog(@"In Save Remaining");
[context save:nil];
[context reset];[pool drain];
}
NSURL*url=[NSURL-URLWithString:@”“;
NSString*responseString=[NSString stringWithContentsOfURL:url编码:NSASCIIStringEncoding错误:nil];
if(响应预算){
NSArray*players=[ResponseStringComponents由字符串分隔:@”;“];
NSU整数循环限制=100,计数=0;
NSAutoreleasePool*池=[[NSAutoreleasePool alloc]init];
NSManagedObjectContext*上下文=[[AppController sharedAppController]managedObjectContext];
[context-setUndoManager:nil];
对于(int i=0;i我看不到任何明显的泄漏,但:
您可以最小化alloc init retain
-ingNSLocale
、NSDateFormatter
、NSNumberFormatter
使用的内存量,然后在循环完成后释放它们。这些似乎在循环运行之间不会改变
我不知道核心数据,但是NSManagedObject
/Player*Player
对象在哪里发布?这是通过核心数据自动发布的吗
另外,您可以使用[list lastObject]
而不是[list count]
和[list objectAtIndex:0]
,因为如果list为零,最后两个将崩溃
根据答复更新:
如果看起来没有什么不同,那么下一步就是简化代码,以便删除任何错误源
执行我在上面#1中的建议,以尽量减少循环中的代码量
检查是否正在某处释放列表
对象,或者是否将其分配为自动释放
删除中间保存(所有count==LOOP\u LIMIT
)并仅在处理完所有数组后保存和排空池。如果(count!=0)
error:nil
语句替换为适当的error:&&error
并记录错误。要记录错误,请执行以下操作(抱歉,代码格式似乎不起作用-不知道原因):
NSError*error=nil;//预先声明
//您简化的代码
/..
error=nil;//就在fetchRequest或context之前:save
/*遍历所有代码后,现在尝试保存*/
if(![context save:&error]){
}
executeFetchRequest
)。值得一试,以找出此处的错误我也看不到代码中有任何可疑之处。日志中肯定没有出现错误
顺便说一句,核心数据pdf中介绍的用于导入数据的另一个优化技巧是将谓词创建移到循环之外,并使用替换变量。[池漏]在结尾处缺失-我刚刚添加了,但这不应该影响实际导入。导入过程中仍然必须存在一些错误。NSManagedObject播放器应该与我相信的池一起发布。不幸的是,它仍然崩溃,我不知道为什么。更新了我的原始响应,添加了更多选项和注释。我已经emove了我以前的评论,因为它们太小,无法读取代码。没有任何错误。我最终通过将LOOP_限制提高到10000,使它能够正常工作。现在它在模拟器和设备上都能正常工作,但在仪器上却不能正常工作。幸运的是,这只在应用程序的初始启动时完成,所以我认为这不应该是一个问题。上面的编辑更改为1000而不是10000。
NSLog(@"Failed to save to data store: %@", [error localizedDescription]);
NSArray *detailedErrors = [[error userInfo] objectForKey:NSDetailedErrorsKey];
if(detailedErrors != nil && [detailedErrors count] > 0) {
for(NSError *detailedError in detailedErrors) {
NSLog(@"DetailedError: %@", [detailedError userInfo]);
}
} else {
NSLog(@" %@", [error userInfo]);
}