2

J'ai certaines sous-classes NSOperations qui gèrent les importations CoreData. Je crois que je l'ai fait tic tac plus du fil non principaux points queNSOperation (s) fuit uniquement sur iOS 3 périphérique

  • Je crée mon propre piscine autorelease dans la méthode main
  • créer un NSManagedObjectContext pour chaque opération

Ces opérations sont chargés dans une NSOperationQueue, avec le nombre maximum d'opérations simultanées défini 1.

Le code fonctionne parfaitement sur un iOS 4.0.1, mais sur un iOS 3.1.3 appareil a obtenir beaucoup de messages de journaux comme le

*** _NSAutoreleaseNoPool(): Object 0x5f926c0 of class NSCFDictionary autoreleased with no pool in place - just leaking 

NSOperation Sous principale méthode

-(void) main{ 

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

    @try { 
    //Start Operation 
    //==================================== 
    NSManagedObjectID  *objID  = nil; 
    NSError    *err  = nil; 
    id        user   = nil; 

    if(!(userID = [self __lookup:[self userID] inContext: [self threadContext]])){ 

     //Set the name of the element 
     user = [[self threadContext] objectWithID:objID]; 
     //Update the name 
     [user setValue:@"John Doe" forKey:@"name"]; 
     [user setValue:@"Hello world" forKey:@"status"]; 
    } 


    if(![[self threadContext] save:&err]){ 
     DebugLog(@"Couldn't savechanges %@", err); 
    } 

    //==================================== 
    //End Operation 
    } 
    @catch (NSException * e) { 
     DebugLog(@"Exception %@",e); 
    } 
    //==================================== 


    [pool drain]; 
} 

La méthode __lookup:inContext:

-(NSManagedObjectID*) __lookup:(id)aID inContext:(NSManagedObjectContext*) aContext{ 

    NSPredicate    *predicate  = nil; 
    NSEntityDescription  *entity; 
    NSFetchRequest   *fetchRequest = nil; 
    NSError     *err   = nil; 

    predicate = [NSPredicate predicateWithFormat:@"userID == %@",aID]; 

    entity = [NSEntityDescription entityForName:@"User" inManagedObjectContext:aContext]; 

    fetchRequest = [[[NSFetchRequest alloc] init] autorelease]; 

    [fetchRequest setPredicate:predicate]; 

    [fetchRequest setEntity:entity]; 

    //Only fetch id's for speed 
    [fetchRequest setResultType:NSManagedObjectIDResultType]; 

    return [[aContext executeFetchRequest:fetchRequest error:&err] lastObject]; 

} 

La plupart des autres méthodes d'instance des méthodes suivantes, à savoir threadContext regard similaire à la méthode __lookup:inContext:. Je suis conscient que je ne crée pas de pools Autorelease pour les méthodes d'instance, mais selon ma compréhension du fonctionnement de l'autorelease, tant que ces méthodes ne sont appelées que dans la méthode principale, une fois que le NSAutoreleasePool a été créé, pool devrait être utilisé. Je crée des objets tels que le NSManagedObjectContext paresseusement, et dans la plupart des cas, ne pas utiliser la méthode start

Répondre

0

résolu le problème, cette opération a été le lancement d'un NSURLConnection utilisant les conseils dans un article par Dave Dribin. Cependant, si possible, j'essaie de ne jamais couper et coller le code d'autres peuples, donc je peux toujours filtrer ce que je mets dans mon propre code.

j'ai oublié sur Turns ajouter cette vérification

if(![NSThread isMainThread]){ 
    [self performSelectorOnMainThread:@selector(start) 
          withObject:nil 
         waitUntilDone:NO]; 
    return; 
} 

qui assure que la méthode start fonctionne sur le thread principal, où un NSAutoreleasePool existe déjà. Erreur simple, solution facile.