Example of how to make a data factory for core data access in cocoa (iPhone)?

I have been slowly learning iPhone development and seem to keep hitting walls where I can't figure out how to do what I want to do the right way :(

Basically, I want a class that handles all interactions with the data layer, for example, getting a mutable array of some list of objects from the data store.

This is pretty trivial in other languages where you have a garbage collector, but in Objective-C on the iPhone, I'm not sure what to do.

This is an example method on a DataFactory class we were creating. Note the comment on where we are not sure when to release....

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

Calling code, related to my comment:

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

Answers


Following naming conventions, your fetchAllDrivers should return an autoreleased object.

- (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];

}

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

By convention, any object returned from the method of an external object is autoreleased. You don't need to retain them except in properties. If you only using arr in the local scope of the method then you don't need to retain/release it. It is autoreleased and will die after the end of the local scope.

If you need to have arr hang around inside the object. You should store it in a retained property:

@property (nonatomic,retain) NSMutableArray *arr;

... then use it with the self notation to ensure retention:

self.arr=[dataFactory fetchAllDrivers];

... then you need only release it in the class' dealloc method.

Having one object manage your data model is very good idea but it is not a "factory". Objective-c does not use factories like C++ and similar languages. Trying to think in those terms will lead to grief. The object should instead be thought of as a "controller" or "manager".


Need Your Help

Hide/Show button based on value from database

c# mysql windows-forms-designer

I have a login button doing the validation of users, but I need this code to check on the table that has a "function id" like 0 and 1, where 1 = show delete button and 0 = hide delete. So, I need the