проблема с нехваткой памяти при импорте данных с Core Data на iPad - PullRequest
0 голосов
/ 13 декабря 2010

У меня возникают проблемы с памятью при импорте данных, когда я извлекаю некоторые XML-данные из веб-службы и сохраняю их в основных данных.

вот мой код:

for (int m=0; m < [manufacturers count]; m++) {

    NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:kClientListURLv2, [[manufacturers objectAtIndex:m]ManufacturerID]]];
    NSLog(@"getting data:%@", url) ;
    NSArray *array = [[NSArray alloc] initWithContentsOfURL:url];
    int j = 0;
    for (NSDictionary* dict in array) {
        j=j+1;
        Client *entity = (Client*) [NSEntityDescription insertNewObjectForEntityForName:@"Client" inManagedObjectContext:managedObjectContext];
        //[entity setValuesForKeysWithDictionary:dict];
        [entity setBillingState:[dict valueForKey:@"BillingState"]];
        [entity setBillingCity:[dict valueForKey:@"BillingCity"]];
        [entity setBillingCountry:[dict valueForKey:@"BillingCountry"]];
        [entity setCurrentBalance:[dict valueForKey:@"CurrentBalance"]];
        [entity setArOver90:[dict valueForKey:@"ArOver90"]];
        [entity setPassword:[dict valueForKey:@"Password"]];
        [entity setPricingDiscount:[dict valueForKey:@"PricingDiscount"]];
        [entity setEmail:[dict valueForKey:@"Email"]];
        [entity setCompanyName:[dict valueForKey:@"CompanyName"]];
        [entity setClientID:[dict valueForKey:@"ClientID"]];
        [entity setAr6190:[dict valueForKey:@"Ar6190"]];
        [entity setBillingAddress2:[dict valueForKey:@"BillingAddress2"]];
        [entity setLastName:[dict valueForKey:@"LastName"]];
        [entity setContactName:[dict valueForKey:@"ContactName"]];
        [entity setAr3160:[dict valueForKey:@"Ar3160"]];
        [entity setSalesRepID:[dict valueForKey:@"SalesRepID"]];
        [entity setShippingAddress2:[dict valueForKey:@"ShippingAddress2"]];
        [entity setShippingCity:[dict valueForKey:@"ShippingCity"]];
        [entity setManufacturerID:[dict valueForKey:@"ManufacturerID"]];
        [entity setShippingState:[dict valueForKey:@"ShippingState"]];
        [entity setAr30:[dict valueForKey:@"Ar30"]];
        [entity setBillingZip:[dict valueForKey:@"BillingZip"]];
        [entity setShippingAddress:[dict valueForKey:@"ShippingAddress"]];
        [entity setShippingZip:[dict valueForKey:@"ShippingZip"]];
        [entity setURL:[dict valueForKey:@"URL"]];
        [entity setPhone:[dict valueForKey:@"Phone"]];
        [entity setCreditLimit:[dict valueForKey:@"CreditLimit"]];
        [entity setClientStatus:[dict valueForKey:@"ClientStatus"]];
        [entity setFax:[dict valueForKey:@"Fax"]];
        [entity setIsDeleted:[dict valueForKey:@"IsDeleted"]];
        [entity setShippingCountry:[dict valueForKey:@"ShippingCountry"]];
        [entity setClientNumber:[dict valueForKey:@"ClientNumber"]];
        [entity setBillingAddress:[dict valueForKey:@"BillingAddress"]];
        [entity setUsername:[dict valueForKey:@"Username"]];
        [entity setIsAddedToServer:[dict valueForKey:@"IsAddedToServer"]];
        [entity setFirstName:[dict valueForKey:@"FirstName"]];
        [entity setRepNumber:[dict valueForKey:@"RepNumber"]];
        [entity setManufacturer:[manufacturers objectAtIndex:m]];
        [entity setIsAddedToServer:[NSNumber numberWithInt:1]];

        for (NSDictionary* dict2 in [dict valueForKey:@"ShippingAddresses"]) {

            if ([[NSString stringWithFormat:@"%@", [dict valueForKey:@"ShippingAddresses"]] length] > 1) {
                ShippingAddress *taggedItem = (ShippingAddress *) [NSEntityDescription insertNewObjectForEntityForName:@"ShippingAddress" inManagedObjectContext:managedObjectContext];
                [taggedItem setValuesForKeysWithDictionary:dict2];
                [taggedItem setClient: entity];

                NSError *error;
                if (![managedObjectContext save:&error]) {
                    NSLog(@"Save Error: %@",error);
                }
            }   
        }

        if (j%saveThreshold==0) {
            NSLog(@"Saving after 500 items");
            NSError *error;
            if (![managedObjectContext save:&error]) {
                NSLog(@"Save Error: %@",error);
            }
        }
    }

    [array release];
    NSError *entityerror;
    if (![managedObjectContext save:&entityerror]) {
        //  //Handle the error.
        NSLog(@"\n\n\n Error saving: %@ \n\n\n\n",entityerror);
    }
}

По сути, это циклическое выполнение и создание всех моих NSManagedObjects, а затем сохранение контекста после каждых 500.

Код работает отлично и работает очень быстро, но объем памяти увеличивается, и, если клиент загружает слишком много файлов, это приводит к сбою приложения из-за нехватки памяти. Есть ли какая-то версия или что-то, что я могу сделать на managedObjectContext - хватаясь за соломинку здесь.

1 Ответ

2 голосов
/ 13 декабря 2010

вы можете попытаться вставить код дыры внутрь

for (int m=0; m < [manufacturers count]; m++) {
}

в отдельный метод и положить

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
[pool drain];

вокруг. Это должно полностью освободить NSArray *array. Не спрашивайте меня, почему он не удален на release, но у меня была такая же проблема несколько недель назад.

Вы можете запустить свой проект с помощью Performance Tools, особенно Object Allocation and Leaks. Он покажет вам, сколько памяти используется в какое время.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...