CoreData插入非常庞大的数据库exc_bad_access

时间:2013-02-07 14:15:06

标签: iphone objective-c core-data insert nsentitydescription

我的数据库中有大约60000个值。 我必须把它们全部保留下来。但是在插入值时我会得到exc_bad_access。 这是我的代码:

if (context == nil)
{
    context = [(radioAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
    NSLog(@"After managedObjectContext: %@",  context);
}

[self performSelectorOnMainThread:@selector(deleteAllFromDB) withObject:nil waitUntilDone:YES];

// here is JSON parsing
int i=0;

@synchronized(self)
{
    NSLog(@"Start");
    NSEntityDescription *entity = [[NSEntityDescription entityForName:@"Station" inManagedObjectContext:context] autorelease];

    for (NSString*string in stations)
    {
        if (![string isEqualToString:@""])
        {
            Station*station = [[[Station alloc] initWithEntity:entity insertIntoManagedObjectContext:nil] retain];

            NSError *err = nil;
            id parsedData = [NSJSONSerialization JSONObjectWithData:[string dataUsingEncoding:NSUTF8StringEncoding]
                                                            options:NSJSONReadingMutableContainers error:&err];
            if (err) {
                NSLog(@"error is %@", [err localizedDescription]);
            }

            [station setName:[parsedData objectForKey:@"nm"]];

            [station setBit: [parsedData objectForKey:@"btr"]];
            [station setEnabled: [NSNumber numberWithInt:1]];

            //encoding id of the station

            scanner = [NSScanner scannerWithString:[parsedData objectForKey:@"id"]];

            [scanner scanHexInt:&tempInt];

            NSNumber *numb = [[NSNumber alloc]initWithInt:i];
            [station setNumber: [NSNumber numberWithInt:[numb intValue]]];

            //encoding country ID

            numb = [NSNumber numberWithInt:i];
            [station setCountryID: [NSNumber numberWithInt:[numb intValue]]];

            //encoding genre ID
            numb = [NSNumber numberWithInt:i];
            [station setGenerID:[NSNumber numberWithInt:[numb intValue]]];

            [station setOrder:[NSNumber numberWithInt:i]];

            [context insertObject:station];

            float k = [stations count];
            k = (i + 1)/k;

            [self performSelectorOnMainThread:@selector(increaseProgress:) withObject:[NSNumber numberWithFloat:k] waitUntilDone:YES];

            i++;

            [scanner release];
            [numb release];
            [station release];
            [parsedData release];
        }
    }

    [context save:nil];
    [entity release];

    NSLog(@"Stop"); 

    NSEntityDescription *entityGen = [NSEntityDescription entityForName:@"Genre" inManagedObjectContext:context];

    NSURL* urlForGenre = [NSURL URLWithString:@"xxx.xxx"];
    NSData *genres = [[NSData alloc] initWithContentsOfURL:urlForGenre];

    NSError *err = nil;
    NSArray *parsedGenres = [NSJSONSerialization JSONObjectWithData:genres options:NSJSONReadingMutableContainers error:&err];
    if (err)
    {
        NSLog(@"error is %@", [err localizedDescription]);
    }


    for (int i =0; i<parsedGenres.count; i++)
    {
        Genre*gen = [[Genre alloc] initWithEntity:entityGen insertIntoManagedObjectContext:nil];

        gen.name = [[parsedGenres objectAtIndex:i] objectForKey:@"nm"];

        int tempInt;
        NSScanner *scanner= [[NSScanner alloc] init];
        scanner = [NSScanner scannerWithString:[[parsedGenres objectAtIndex:i] objectForKey:@"id"]];

        [scanner scanInt:&tempInt];

        NSNumber *numb = [[NSNumber alloc] init];
        numb = [NSNumber numberWithInt:tempInt];

        gen.number = [NSNumber numberWithInt:[numb integerValue]];

        float k = [parsedGenres count];
        k = (i + 1)/k;

        [self performSelectorOnMainThread:@selector(increaseProgress:) withObject:[NSNumber numberWithFloat:k] waitUntilDone:YES];
        [context insertObject:gen];

        [gen release];
    }

    [entityGen release];
    [context save:nil];

    NSEntityDescription *entityCon = [NSEntityDescription entityForName:@"Country" inManagedObjectContext:context];

    NSURL* urlForCoun = [NSURL URLWithString:@"yyy.yyy"];
    NSData *countr = [[NSData alloc] initWithContentsOfURL:urlForCoun];

    err = nil;
    NSArray *parsedCountr = [NSJSONSerialization JSONObjectWithData:countr options:NSJSONReadingMutableContainers error:&err];
    if (err)
    {
        NSLog(@"error is %@", [err localizedDescription]);
    }

    NSMutableArray* temp = [[NSMutableArray alloc] init];

    for (int i =0; i<parsedCountr.count; i++)
    {
        Country*countr = [countr initWithEntity:entityCon insertIntoManagedObjectContext:nil];

        countr.name = [[parsedCountr objectAtIndex:i] objectForKey:@"nm"];

        int tempInt;
        NSScanner *scanner= [[NSScanner alloc] init];
        scanner = [NSScanner scannerWithString:[[parsedCountr objectAtIndex:i] objectForKey:@"id"]];

        [scanner scanInt:&tempInt];

        NSNumber *numb = [[NSNumber alloc] init];
        numb = [NSNumber numberWithInt:tempInt];

        countr.number = [NSNumber numberWithInt:[numb integerValue]];

        [temp addObject:countr];

        float k = [parsedCountr count];
        k = (i + 1)/k;

        [self performSelectorOnMainThread:@selector(increaseProgress:) withObject:[NSNumber numberWithFloat:k] waitUntilDone:YES];

        [context insertObject:countr];

        [countr release];
    }

    [context save:nil];

如果我的应用程序没有崩溃,是的,它不是每次发布都会发生的。它崩溃了:

Country*countr = [countr initWithEntity:entityCon insertIntoManagedObjectContext:nil];

请帮忙!对不起我糟糕的英语。

更新

在:     Country * countr = [countr initWithEntity:entityCon insertIntoManagedObjectContext:nil];

  

主题7:EXC_BAD_ACCESS(代码= 1,地址= 0x3f800008)

其他错误也是exc_bad_access。但是使用code = 2和其他线程。

更新2:

我在调试方案中启用了僵尸模式。什么都没发生。

更新3:

我认为我的记忆存在问题。

  

GuardMalloc:VM无法分配4128字节

     

GuardMalloc:明确陷入调试器!!!

2 个答案:

答案 0 :(得分:0)

您无法将nil managedObjectContext参数传递给initWithEntity:insertIntoManagedObjectContext:方法。尝试更改此内容:

Country*countr = [countr initWithEntity:entityCon insertIntoManagedObjectContext:nil];

到这个

// pass managed object context parameter
Country*countr = [countr initWithEntity:entityCon insertIntoManagedObjectContext:context];

答案 1 :(得分:0)

根据documentation和我的经验,您可以将nil作为managedObjectContext传递。

我还得到了一个EXC_BAD_ACCESS,原因是我没有保留托管对象模型(我只创建了一个模型来获取实体描述然后它被释放了。)

特别是,这就是我在做的事情:

在测试类中,在setUp方法中:

- (void)setUp
{
    [super setUp];

    NSBundle *bundle = [NSBundle bundleForClass:[self class]];
    NSURL *modelURL = [bundle URLForResource:@"TestDatamodel" withExtension:@"momd"];
    NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
    STAssertNotNil(model, nil);

    _entity = [[model entitiesByName] objectForKey:NSStringFromClass([MyEntity class])];
    STAssertNotNil(_entity, nil);
    // ...
}

然后在测试方法中我创建了一个没有像这样的上下文的托管对象:

NSManagedObject *object = [[NSManagedObject alloc] initWithEntity:_entity insertIntoManagedObjectContext:nil];

我在这里得到了EXC_BAD_ACCESS。

解决方案是在测试类中添加一个ivar,以保持对托管对象模型的引用。