Объединение всего кода данных ядра в его собственный класс - PullRequest
1 голос
/ 17 февраля 2012

Я начал создавать приложение, которое использует базовый стек данных на заднем плане. Он имеет различные объекты в стеке (в частности, 3), каждый из которых доступен для другого контроллера табличного представления. Так, например, у меня есть объект «Клиент», который доступен контроллеру табличного представления. После выбора клиента вызывается новый контроллер табличного представления, который отображает записи в сущности «Автомобили» и т. Д. *

В данный момент я последовал предложению Apple передать 'managedObjectContext' по цепочке (так сказать), которая была создана в AppDelegate. Это действительно работает, но это означает, что весь мой код, который получает доступ, добавляет и удаляет управляемые объекты в стеке, интегрирован во все мои контроллеры представления.

Я бы подумал, что было бы чище (и лучше реализовать MVC) создать класс 'CoreDataModel', который обрабатывает все взаимодействия с моим стеком, и каждый view-контроллер может вызывать его по мере необходимости.

Во-первых, кажется ли это разумным / достижимым?

Во-вторых, в моей реализации я сохранил весь код настройки основных данных в AppDelegate и назначил managedObjectContext новому экземпляру моего класса CoreDataModel. Однако в моем первом viewcontroller я вызываю метод экземпляра моего класса CoreDataModel с именем (NSMutableArray *) retrieveClientList {}. Я настроил небольшой отчет NSLog, когда метод вызывается правильно, но, похоже, он не вызывается.

В качестве справки я вставил код из своего пользовательского класса, а также из AppDelegate и первого viewcontroller. [Существует первый rootview-контроллер перед первым tableview-контроллером, который является просто главным меню, которое я не вставил сюда, так как не думаю, что это имеет значение]

Любые указатели, с благодарностью ...

Это реализация моего пользовательского класса CoreDataModel ...

@implementation CoreDataModel

@synthesize managedObjectContext;

-(NSMutableArray *)retrieveClientList {

// Create fetch request
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Client" inManagedObjectContext:managedObjectContext];
[request setEntity:entity];

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];

[request setSortDescriptors:sortDescriptors];
[sortDescriptors release];
[sortDescriptor release];

NSError *error = nil;
NSMutableArray *mutableFetchResults = [[managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
if(mutableFetchResults == nil) {
    // Handle the error
}

NSLog(@"Got here!");
return mutableFetchResults;

}

@end

Это реализация моего AppDelegate ...

@implementation iPTAppDelegate

@synthesize window;
@synthesize navigationController;
@synthesize managedObjectContext;

#pragma mark -
#pragma mark Application lifecycle

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    

// Create new CoreDataModel object
CoreDataModel *coreDataModel = [[CoreDataModel alloc] init];

NSManagedObjectContext *context = [self managedObjectContext];
if (!context) {
    //Handle the error
}
//Pass the managed object context to the new CoreDataModel object
coreDataModel.managedObjectContext = context;


//Set the navigation controller as the window's root view controller and display
RootViewController *rootViewController = [[RootViewController alloc] initWithStyle:UITableViewStyleGrouped];


UINavigationController *aNavigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController];
self.navigationController = aNavigationController;

[window addSubview:[navigationController view]];
[window makeKeyAndVisible];

[coreDataModel release];
[rootViewController release];
[aNavigationController release];

return YES;
}

И, наконец, это мой первый view-контроллер ...

#import "ClientListViewController.h"
#import "ClientViewController.h"
#import "CoreDataModel.h"

@implementation ClientListViewController

@synthesize clientsArray;
@synthesize coreDataModel;


#pragma mark -
#pragma mark View lifecycle


- (void)viewDidLoad {
[super viewDidLoad];

// Set the title
self.title=@"Clients";

// Add the + button
// self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemEdit target:self action:@selector(editMode)] autorelease];
self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(callAddClientViewController)] autorelease];

[self populateTable];
}

-(void)populateTable {

NSLog(@"Called here");
[self setClientsArray:[coreDataModel retrieveClientList]];

}

Ответы [ 2 ]

1 голос
/ 17 февраля 2012

Один комментарий к дизайну, я думаю, что эти вещи чаще всего реализуются как одиночные (см. Множество примеров здесь, чтобы узнать, как их создать).

В данный момент ваш не работает, потому что вы не передаете объект модели данных ядра вашему контроллеру представления.Я ожидаю увидеть rootViewController.coreDataModel = coreDataModel в вашем делегате приложения после создания VC.

1 голос
/ 17 февраля 2012

Я согласен, что сохранение кода базы данных настолько чистым, насколько это возможно, я также использую некий синглтон CoreDataModel, из которого я могу запросить контекст или другие классы, связанные с CoreData.

Для кода, который работает с сущностями, я использую «mogenerator» для генерации объектов данных из моделей Core Data.

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

Так, например, если у вас есть сущность Cat, вы можете иметь такие вещи:

+ (Cat*) newCatWithID:(NSString *)id;
+ (NSArray *) catsWithHairType:(NSInteger)hairType;
- (NSDictionary *) catComponentsInHumanReadableStrings;

Вы понимаете, что каждый из этих методов может хранить операции с базовыми данными внутри этого класса, а не распространяться по всему вашему коду. Тогда другим классам нужно только просматривать и использовать ваши объекты данных, не зная Базовых Данных (за исключением того, что им может потребоваться сохранить, но вы можете попросить вашу общую модель обработать это).

...