2010-12-13 4 views
0

Je rencontre des problèmes de mémoire avec mon importation de données où je tire un peu de xml d'un service Web et l'enregistre dans les données de base.problème de mémoire faible lors de l'importation de données avec des données de base sur iPad

voici mon code:

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); 
    } 
} 

En gros, cela est une boucle à travers la création et tous mes NSManagedObjects puis en enregistrant le contexte après chaque 500.

code fonctionne très bien et est très rapide, mais la mémoire se développe et s'il y a aussi des clients téléchargés, il bloque l'application en raison de la mémoire insuffisante. Y a-t-il une sorte de release ou quelque chose que je peux faire sur le managedObjectContext - en attrapant des pailles ici.

Répondre

2

vous pouvez essayer de mettre le code de trou à l'intérieur

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

dans une méthode séparée et mettre un peu

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

autour d'elle. Cela devrait libérer tout NSArray *array complètement. Ne me demandez pas pourquoi il n'est pas supprimé sur release mais j'ai eu le même problème il y a quelques semaines.

Vous pouvez exécuter votre projet avec Performance Tools et en particulier Object Allocation and Leaks. Il vous montrera, combien de mémoire est utilisée à quel moment.

+0

cela a aidé avec d'autres parties de ce code, mais je vais devoir diviser mon importation en différents morceaux, la taille totale de téléchargement de données est maintenant plus de 3O Megs. Je pense que l'ouverture est beaucoup trop de mémoire. – Slee

+0

vous devriez certainement diviser le fichier de téléchargement. L'iPhone 3G a seulement environ 40mb de mémoire utilisable. Vous pouvez également essayer de créer un analyseur qui décomposera les objets en en téléchargeant de nouveaux. (Je pense qu'il y a déjà un analyseur à partir de l'url ...) Ce serait beaucoup plus facile si vous avez plusieurs fichiers et que vous les chargez séparément, analysez-les avec AutoreleasePool et chargez le suivant. –

Questions connexes