我已经开始创建一个在后端使用核心数据堆栈的应用程序。它具有堆栈内的各种实体(具体为3个),每个实体可由不同的表视图控制器访问。因此,例如,我有一个可以由表视图控制器访问的“客户端”实体。选择客户端后,将调用一个新的表视图控制器,在“汽车”实体等中显示记录......
目前,我已经遵循Apple的建议,即将'managedObjectContext'传递给在AppDelegate中创建的链(可以这么说)。这确实有效,但这意味着我在堆栈中访问,添加和删除managedObjects的所有代码都集成在我的所有视图控制器中。
我认为创建一个'CoreDataModel'类更干净(以及更好的MVC实现),它处理与我的堆栈的所有交互,每个viewcontroller都可以根据需要调用它。
首先,这看起来是否合理/可实现?
其次,在我的实现中,我将所有核心数据设置代码保存在AppDelegate中,并将managedObjectContext分配给我的CoreDataModel类的新实例。但是,在我的第一个viewcontroller中,我调用了一个名为(NSMutableArray *)retrieveClientList {}的CoreDataModel类的实例方法。我在正确调用方法时设置了一个小的NSLog报告,但这似乎没有被调用。
作为帮助,我已经粘贴了我的自定义类的代码,以及AppDelegate和第一个viewcontroller。 [在第一个tableviewcontroller之前有一个rootviewcontroller,它只是一个我没有粘贴在这里的主菜单,因为我觉得不重要]
任何指针,非常感谢...
这是我的自定义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;
}
最后,这是我的第一个viewcontroller ......
#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]];
}
答案 0 :(得分:1)
我同意保持数据库代码尽可能多清晰,我也使用一种CoreDataModel单例,我可以从中请求上下文或其他与CoreData相关的类。
对于与实体一起使用的代码,我使用“mogenerator”从Core Data模型生成数据对象。
此工具为每个实体输出两组类 - 一个类表示实体访问器,另一个类继承该类,表示可以放置所有与Core Data相关的代码的类。
因此,例如,如果您有Cat实体,则可以使用以下内容:
+ (Cat*) newCatWithID:(NSString *)id;
+ (NSArray *) catsWithHairType:(NSInteger)hairType;
- (NSDictionary *) catComponentsInHumanReadableStrings;
您明白了,这些方法中的每一个都可以将Core Data操作保留在该类中,而不是遍布整个代码。然后其他类只需要查看和使用您的数据对象,而不需要知道核心数据(除非他们可能需要保存,但您可以要求您的共享模型来处理)。
答案 1 :(得分:1)
关于设计的一个评论,我认为这些东西通常更多地被实现为单身(这里有很多关于如何创建单例的例子)。
目前,您的工作不正常,因为您没有将核心数据模型对象传递给视图控制器。在创建VC后,我希望在您的app委托中看到rootViewController.coreDataModel = coreDataModel
。