0

Je suis lentement apprendre le développement de l'iPhone et semblent garder les murs frapper là où je ne peux pas savoir comment faire ce que je veux faire de la bonne façon :(Exemple de création d'une fabrique de données pour l'accès aux données de base dans le cacao (iPhone)?

Fondamentalement, je veux une classe qui gère toutes les interactions avec la couche de données, par exemple, obtenir un tableau mutable d'une liste d'objets du magasin de données

Ceci est assez trivial dans d'autres langues où vous avez un garbage collector, mais en Objective-C sur l'iPhone, je '' Je ne suis pas sûr quoi faire

Ceci est un exemple de méthode sur une classe DataFactory que nous étions en train de créer Notez le commentaire sur où nous ne sommes pas sûrs quand nous allons publier ....

- (NSMutableArray*)fetchAllDrivers{ 

    NSMutableArray *results = [[NSMutableArray alloc] init];; 

    if (self.appDelegate != nil) { 
     NSManagedObjectContext *context = [self.appDelegate managedObjectContext]; 

     NSFetchRequest *request = [[NSFetchRequest alloc] init]; 
     NSEntityDescription *entity = [NSEntityDescription entityForName:@"Person" inManagedObjectContext:context]; 
     [request setEntity: entity]; 

     NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"lastName" ascending:NO]; 
     NSArray *sortDescriptors = [[NSArray alloc] initWithObjects: sortDescriptor, nil]; 
     [request setSortDescriptors: sortDescriptors]; 
     [sortDescriptors release]; 
     [sortDescriptor release]; 

     NSError *error; 
     results = [[context executeFetchRequest:request error:&error] mutableCopy]; 
     if (results == nil) { 
      //something went wrong 
     } 

     //Where should this be released??? Certainly not here! 
     [results release]; 

     [request release]; 
    } 
    else { 
     [NSException raise:@"Can't fetch b/c app delgate is nil!" format: @"!!!"];  
    } 

    return results; 
} 

Indicatif téléphonique, lié à mon commentaire:

NSMutableArray* arr = [dataFactory fetchAllDrivers]; 
[arr retain]; 
//Some code where we use arr 
[arr release]; 

Répondre

1

aux conventions de dénomination, votre fetchAllDrivers doit retourner un objet autoreleased.

- (NSMutableArray*)fetchAllDrivers 
{ 

    if (!self.appDelegate) { 
     // Big Problems Raise exception immediately if you want... 
     return nil; 
    } 

    NSManagedObjectContext *context = [self.appDelegate managedObjectContext]; 

    NSFetchRequest *request = [[NSFetchRequest alloc] init]; 
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Person" inManagedObjectContext:context]; 
    [request setEntity: entity]; 

    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"lastName" ascending:NO]; 
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects: sortDescriptor, nil]; 
    [request setSortDescriptors: sortDescriptors]; 
    [sortDescriptors release]; 
    [sortDescriptor release]; 


    NSError *error = nil; 

    NSMutableArray *results = [[NSMutableArray alloc] initWithArray:[context executeFetchRequest:request error:&error] copyItems:YES]; 

    if (error) { 
     // Something went wrong 
     [results release]; 
     // Error handling code here 
     [request release]; 
     return nil; 
    } 

    [request release]; 
    return [results autorelease]; 

} 
+0

Ah, je me demandais quand utiliser autorelease! Donc, si je me souviens de mon apprentissage de la gestion de la mémoire correctement, le code appelant devra impliquer la propriété dans l'objet retourné droit? (voir le code que j'ai ajouté au bas de ma question) – spilliton

+0

Vous avez le groove maintenant. Vous devriez vérifier que arr n'est pas nul. – falconcreek

1
NSMutableArray* arr = [dataFactory fetchAllDrivers]; 
[arr retain]; 
//Some code where we use arr 
[arr release]; 

Par convention, tout objet retourné par la méthode d'un objet extérieur est autoreleased. Vous n'avez pas besoin de les conserver sauf dans les propriétés. Si vous utilisez uniquement arr dans la portée locale de la méthode, vous n'avez pas besoin de le conserver/libérer. Il est auto-libéré et mourra après la fin de la portée locale.

Si vous avez besoin d'avoir arr traîner à l'intérieur de l'objet. Vous devez stocker dans une propriété retenue:

@property (nonatomic,retain) NSMutableArray *arr; 

... utiliser ensuite avec la notation auto pour assurer la rétention:

self.arr=[dataFactory fetchAllDrivers]; 

... alors vous avez besoin de libérer seulement dans la classe dealloc méthode.

Avoir un objet gérer votre modèle de données est une très bonne idée mais ce n'est pas une "usine". Objective-c n'utilise pas d'usines comme C++ et des langages similaires. Essayer de penser en ces termes mènera au chagrin. L'objet devrait plutôt être considéré comme un "contrôleur" ou un "gestionnaire".

+0

Nous allons en fait stocker arr dans une propriété (c'est la source de données pour une table), donc merci pour l'explication! En outre, la friandise de ne pas avoir à retenir dans le cadre d'une méthode lorsque vous recevez un objet autorelease, cela a aussi du sens. Merci! – spilliton