2010-12-13 3 views
0

Ich habe einige Speicherprobleme mit meinem Datenimport, wo ich etwas XML von einem Webdienst abrufe und in den Kerndaten speichere.Problem mit wenig Speicher beim Datenimport mit Core Data auf dem iPad

hier ist mein 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); 
    } 
} 

Im Grunde ist dies durch geloopt und alle meine NSManagedObjects erstellen und dann den Kontext Speichern nach jedem 500.

-Code große Arbeit und ist sehr schnell, aber Speicher wächst Wenn Clients heruntergeladen werden, stürzt die App ab, weil der Arbeitsspeicher knapp ist. Gibt es eine Art von Release oder etwas, was ich auf dem ManagedObjectContext tun kann - greifen hier auf Strohhalme. innen

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

in einem separaten Verfahren und setzen einige

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

um es

Antwort

2

können Sie versuchen, das Loch Code zu setzen. Dies sollte NSArray *array vollständig freigeben. Fragen Sie mich nicht, warum es nicht auf release gelöscht wird, aber ich hatte das gleiche Problem vor ein paar Wochen.

Sie können Ihr Projekt mit Performance Tools und insbesondere Object Allocation and Leaks ausführen. Es zeigt Ihnen, wie viel Speicher zu welcher Zeit verwendet wird.

+0

dies half mit anderen Teilen dieses Codes, aber ich werde meinen Import in verschiedene Stücke teilen müssen, Gesamtdaten Downloadgröße ist jetzt über 3O Megs. Ich denke, Öffnung, die viel Speicher allein aufstellt. – Slee

+0

sollten Sie die Download-Datei auf jeden Fall teilen. iPhone 3G hat nur etwa 40 MB nutzbaren Speicher. Sie können auch versuchen, einen Parser zu erstellen, der die Objekte beim Herunterladen neuer Objekte zerlegt. (Ich denke, es gibt bereits einen Parser von der URL ...) Es wäre viel einfacher, wenn Sie mehrere Dateien haben und laden Sie jede separate, parsen Sie es mit AutoreleasePool und laden Sie dann die nächste. –