【问题标题】:Collating all core data code into its own class将所有核心数据代码整理到自己的类中
【发布时间】:2012-03-09 03:01:36
【问题描述】:

我已经开始创建一个在后端使用核心数据堆栈的应用程序。它在堆栈中有各种实体(特别是 3 个),每个实体都可由不同的表视图控制器访问。因此,例如,我有一个表视图控制器可以访问的“客户端”实体。一旦选择了一个客户端,就会调用一个新的表视图控制器来显示“汽车”实体等中的记录...

目前,我遵循 Apple 的建议,将“managedObjectContext”传递到在 AppDelegate 中创建的链(可以这么说)。这确实有效,但这意味着我在堆栈中访问、添加和删除 managedObjects 的所有代码都集成在我的所有视图控制器中。

我认为创建一个“CoreDataModel”类来处理与我的堆栈的所有交互并且每个视图控制器都可以根据需要调用它会更简洁(并且是 MVC 的更好实现)。

首先,这看起来合理/可行吗?

其次,在我的实现中,我将所有核心数据设置代码保留在 AppDelegate 中,并将 managedObjectContext 分配给我的 CoreDataModel 类的新实例。然而,在我的第一个视图控制器中,我调用了我的 CoreDataModel 类的一个实例方法,称为 (NSMutableArray *)retrieveClientList{}。当方法被正确调用时,我已经设置了一个小的 NSLog 报告,但这似乎没有被调用。

作为帮助,我粘贴了自定义类中的代码,以及 AppDelegate 和第一个视图控制器。 [在第一个 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;
}

最后,这是我的第一个视图控制器...

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

}

【问题讨论】:

    标签: ios core-data


    【解决方案1】:

    关于设计的一条评论,我认为这些东西更通常作为单例实现(有关如何创建单例,请参见此处的大量示例)。

    目前,您的方法不起作用,因为您没有将核心数据模型对象传递给您的视图控制器。在您创建 VC 后,我希望在您的应用程序委托中看到 rootViewController.coreDataModel = coreDataModel

    【讨论】:

    • 啊——完美!!是的,现在有效。虽然我必须承认我不完全理解为什么。我可以检查一下...大概我在 AppDelegate 中创建了一个 CoreDataModel 实例。但是,由于我没有将它传递给视图控制器,所以当我调用实例方法时,它没有 CoreDataModel 的实例来使用该方法吗?感谢单身人士的指针,我需要更全面地调查它们。我不知道如何使用它们。
    • 你的推理完全正确。您可以在 obj-c 中向 nil 发送消息,它会愉快地忽略它们,这就是您在 VC 中所拥有的。
    【解决方案2】:

    我同意尽可能多地保留数据库代码更简洁,我还使用一种 CoreDataModel 单例,我可以从中请求上下文或其他与 CoreData 相关的类。

    对于与实体一起使用的代码,我使用“mogenerator”从 Core Data 模型生成数据对象。

    这个工具为每个实体输出两组类——一个类代表实体访问器,另一个类继承自该类并代表一个类,您可以在其中放置所有与 Core Data 相关的代码。

    例如,如果你有一个 Cat 实体,你可以有这样的东西:

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

    您明白了,这些方法中的每一个都可以将 Core Data 操作保留在该类中,而不是在您的代码中到处传播。然后其他类只需要查看和使用您的数据对象,而无需了解 Core Data(除非它们可能需要保存,但您可以要求您的共享模型来处理)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-31
      • 2012-03-03
      • 2015-02-26
      • 1970-01-01
      • 1970-01-01
      • 2010-11-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多