2010-12-07 11 views
0

J'essaie d'ajouter des données à CoreData. Cela fonctionne bien quand je construis à partir de Xcode au téléphone mais quand j'essaye de lancer l'application directement à partir de l'iPhone il se bloque à la première sauvegarde au contexte.Ajout d'un grand nombre de propriétés dans les données de base, écrasement lors du démarrage à partir du téléphone mais pas de Xcode

Je lis un fichier texte qui est synchronisé via le partage de fichiers iTunes, le fichier est assez gros (~ 350 000 lignes). Les valeurs que je reçois du fichier sont ajoutées à deux tableaux différents (codes à barres et noms de produit). Les tableaux sont ensuite groupés et envoyés à la fonction où je sauvegarde les données.

de la boucle de tableau: [...]

 words = [rawText componentsSeparatedByString:@";"]; 

    int loopCounter = 0; 
    int loopLimit = 20000; 

    int n = 0; 
    int wordType; 
    NSEnumerator *word = [words objectEnumerator]; 
    NSLog(@"Create arrays"); 
    while(tmpWord = [word nextObject]) { 

     if ([tmpWord isEqualToString: @""] || [tmpWord isEqualToString: @"\r\n"]) { 
      //   NSLog(@"%@*** NOTHING *** ",tmpWord); 
     }else { 



      n++; 
      wordType = n%2; 

      if (wordType == kBarcode) { 
       [barcodes addObject: tmpWord]; 

      }else if (wordType == kProduct) { 
       [productNames addObject: tmpWord]; 
      } 
      // Send to batch // 
      loopCounter ++; 

      if (loopCounter == loopLimit) { 
       loopCounter = 0; 
       NSLog(@"adding new batch"); 
       [self addBatchOfData]; 

       [barcodes release]; 
       [productNames release]; 

       barcodes = [[NSMutableArray arrayWithCapacity:20000] retain]; 
       productNames = [[NSMutableArray arrayWithCapacity:20000] retain]; 


      } 

     } 

[...]

Et puis la fonction de sauvegarde:

-(void)addBatchOfData { 
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
NSError *error; 

NSUInteger loopLimit = 5000; 
NSUInteger loopCounter = 0; 

NSString *ean; 
NSString *designation; 

for (int i=0; i<[barcodes count];i++) { 

    ean = [barcodes objectAtIndex:i]; 
    designation = [productNames objectAtIndex:i]; 

    Product *product = (Product *)[NSEntityDescription insertNewObjectForEntityForName:@"Product" inManagedObjectContext:importContext]; 
    [product setDesignation:designation]; 
    [product setBarcode:ean]; 

    loopCounter ++; 
    if (loopCounter == loopLimit) { 
     NSLog(@"Save CoreData"); 
     [importContext save:&error]; 
     [importContext reset]; 
     [pool drain]; 

     pool = [[NSAutoreleasePool alloc] init]; 

     loopCounter = 0; 
    } 
} 
// Save any remaining records 
if (loopCounter != 0) { 
    [importContext save:&error]; 
    [importContext reset]; 
} 
[pool drain]; 

}

C'est vraiment énervant que ça marche bien quand je construis à partir de Xcode. Heureusement il y a un paramètre que j'ai manqué ou quelque chose ...

EDIT: J'ai oublié de mentionner que je n'ai pas passé l'écran par défaut et je n'ai aucun journal. Cela peut-il avoir quelque chose à voir avec l'approvisionnement?

Répondre

0

Déchargez le chargement de votre fichier dans un fil d'arrière-plan et laissez le téléphone démarrer votre fenêtre principale et afficher. iOS va tuer votre application si vous ne présentez pas une vue en temps opportun (c'est ce que vous voyez).

Je dois faire quelque chose comme ça pour mon code convertisseur xml -> CoreData. Je viens de présenter à l'utilisateur une vue les informant de ce qui se passe et une barre de progression (j'utilise https://github.com/matej/MBProgressHUD). quelque chose comme:

self.hud = [[MBProgressHUD alloc] initWithView:window]; 

// Set determinate mode 
hud.mode = MBProgressHUDModeDeterminate; 
hud.delegate = self; 
hud.labelText = @"Converting Data File"; 
[self.window addSubview:hud]; 

// Show the HUD while the provided method executes in a new thread 
[hud showWhileExecuting:@selector(convertToCoreDataStoreTask) onTarget:self withObject:nil animated:YES]; 

Il vous suffit de vous assurer que vous utilisez un NSManagedObjectContext séparé dans le nouveau fil.

+0

Merci Brent! C'est en fait comme ça que je l'ai résolu. J'ai été surpris à quel point il était facile de créer un nouveau fil. – Mike

0

Je suggère que vous implémentez cette méthode de délégué, puis essayez de voir ce qui se passe avec la mémoire.

lors de l'exécution dans le simulateur, vous avez pas de contraintes de mémoire, mais lors de l'exécution dans le téléphone que vous faites

- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application 
{ 
} 
+0

Merci, le fait est que je ne le lance pas dans le simulateur mais je le construis sur l'appareil. Quand je fais ça, ça marche bien ... – Mike

0

Je pense que je trouve la solution à ma question. Ce que je faisais, c'est que j'ai commencé tout le gros problème de données dans le "- (void) viewDidLoad {". Quand je l'ai changé pour commencer le craquement après avoir cliqué sur un bouton dans l'application, cela a très bien fonctionné.

En ce moment, il est juste de savoir où le début de la crise des données, des suggestions?