在后台线程上保存数据时收到内存警告

时间:2013-03-19 16:04:40

标签: ios core-data memory-management crash nsmanagedobject

我在NSMutableArray(> 2500)中有很多对象,当我保存它时,应用程序崩溃(收到内存警告x3)。

    NSLog(@"start");
    NSInteger saveTemp = 0;
    NSData *data = [NSURLConnection sendSynchronousRequest:req returningResponse:&response error:&err];
    if ([data length] > 0 && err == nil)
    {
        MyClass* rcust;
        NSString *respStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        NSMutableArray* cust = [respStr JSONValue];
        for(NSDictionary *v in cust)
        {
            if([dataProvider getClassById:[[v valueForKey:@"Id"] integerValue] error:nil] == nil)
            {
                rcust = [dataProvider createClass];
                rcust.clsId = [v valueForKey:@"Id"];
            }
            else
            {
                rcust = [dataProvider getClassById:[[v valueForKey:@"Id"] integerValue] error:nil];
            }
            rcust.cstZip = [v valueForKey:@"Zip"] == [NSNull null]? @"": [v valueForKey:@"Zip"];

            saveTemp++;
            if(saveTemp > 1000)
            {
                NSLog(@"save");
               [dataProvider saveContext];
                saveTemp = 0;
            }
        }
        [dataProvider saveContext];
    }

此处为saveContext方法

- (void)saveContext {
    NSError*err = nil;
    if(![[self managedObjectContext] save:&err])
    {
        NSLog(@"Unresolved error %@, %@", err, [err userInfo]);
    }
}

更新: 我在方法中添加了代码,你就是。

2013-03-21 15:18:54.641  start
2013-03-21 15:19:31.843  save
2013-03-21 15:23:21.126  save

即。数据保存速度越来越慢,一段时间后,应用程序崩溃了。

1 个答案:

答案 0 :(得分:0)

因此,看起来您从该NSURLRequest返回了> 2500个客户。当你填充cust数组时,你有四个数据副本(如NSData,NSString,NSMutableArray和NSManagedObjectContext)。

使用@autoreleasepool包装NSData和NSString转换。完成-JSONValue电话后,您不再需要这些陈述。

然后,将处理循环包装在@autoreleasepool中。这将允许释放中间结果(甚至是你看不到的结果)。

最后,当您执行saveContext时,也要对托管对象上下文执行-reset。

另外两个注意事项:

您对第4行中的NSError参数的检查不正确。对于具有NSError **参数的方法,如果操作成功,则NSError返回值未定义。逻辑应为if (data.length > 0)然后继续,否则检查NSError。请参阅NSURLConnection的类引用。

此外,您的getClassById方法似乎违反了Cocoa命名标准。如果方法以单词get开头,则必须通过参数引用返回其结果。请参阅https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CodingGuidelines/Articles/NamingMethods.html#//apple_ref/doc/uid/20001282-BCIGIJJF