Пример того, как сделать фабрику данных для доступа к основным данным в какао (iPhone)? - PullRequest
0 голосов
/ 09 июля 2010

Я медленно изучаю разработку для iPhone и, похоже, продолжаю бить по стенам, где я не могу понять, как сделать то, что я хочу сделать правильно: (

По сути, мне нужен класс, который обрабатывает все взаимодействия со слоем данных, например, получает изменяемый массив некоторого списка объектов из хранилища данных.

Это довольно тривиально на других языках, где у вас есть сборщик мусора, но в Objective-C на iPhone я не уверен, что делать.

Это пример метода для класса DataFactory, который мы создавали. Обратите внимание на комментарий о том, где мы не уверены, когда выпустить ....

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

Телефонный код, связанный с моим комментарием:

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

Ответы [ 2 ]

1 голос
/ 10 июля 2010
NSMutableArray* arr = [dataFactory fetchAllDrivers];
[arr retain];
//Some code  where we use arr
[arr release];

По соглашению, любой объект, возвращаемый методом внешнего объекта, автоматически освобождается. Вам не нужно сохранять их, кроме как в свойствах. Если вы используете только arr в локальной области действия метода, вам не нужно сохранять / освобождать его. Это автоматически выпущено и умрет после окончания локальной области видимости.

Если вам нужно, чтобы arr зависал внутри объекта. Вы должны хранить его в оставшейся собственности:

@property (nonatomic,retain) NSMutableArray *arr;

... затем используйте его с собственной нотацией для сохранения:

self.arr=[dataFactory fetchAllDrivers];

... тогда вам нужно только освободить его в методе класса dealloc.

Наличие одного объекта для управления моделью данных - очень хорошая идея, но это не "фабрика". Objective-c не использует фабрики, такие как C ++ и подобные языки. Попытка думать в этих терминах приведет к горе. Вместо этого объект следует рассматривать как «контроллер» или «менеджер».

1 голос
/ 09 июля 2010

В соответствии с соглашениями об именах ваш fetchAllDrivers должен возвращать 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];

}
...