Iphone 如何在RootViewController之外的另一个视图上加载核心数据?

Iphone 如何在RootViewController之外的另一个视图上加载核心数据?,iphone,cocoa-touch,core-data,ios4,uiviewcontroller,Iphone,Cocoa Touch,Core Data,Ios4,Uiviewcontroller,除了AppDelegate中的代码外,我的核心数据和应用程序基本正常工作。我遇到的问题代码如下: - (void)applicationDidFinishLaunching:(UIApplication *)application { RootViewController *tableController = [[RootViewController alloc] initWithStyle:UITableViewStylePlain]; tableController

除了AppDelegate中的代码外,我的核心数据和应用程序基本正常工作。我遇到的问题代码如下:

- (void)applicationDidFinishLaunching:(UIApplication *)application {    

    RootViewController *tableController = [[RootViewController alloc] initWithStyle:UITableViewStylePlain];
    tableController.managedObjectContext = [self managedObjectContext];

    self.navigationController = [[UINavigationController alloc] initWithRootViewController:tableController];
    [tableController release];

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

}
我不想让managedObjectContext在启动时成为根视图控制器。我想让它成为另一个视图控制器。但是,如果我将类更改为我需要的视图控制器,它会在应用程序启动时加载该视图控制器,这不是我想要做的。我仍然希望启动根视图,但我希望能够加载其他视图控制器的核心数据上下文。我真的很困惑如何解决这个问题。到目前为止,我已经花了两天的时间试图找到一种方法来解决这个问题,但还没有找到运气。任何帮助都将不胜感激

此外,如果我在appdelegate didfinishlaunching中遗漏以下内容:

RootViewController *tableController = [[RootViewController alloc] initWithStyle:UITableViewStylePlain];
        tableController.managedObjectContext = [self managedObjectContext];

        self.navigationController = [[UINavigationController alloc] initWithRootViewController:tableController];
        [tableController release];
我得到这个错误:

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '+entityForName: could not locate an NSManagedObjectModel for entity name 'Hello'
编辑: 以下是实体代码:

- (void)viewDidLoad {
    [super viewDidLoad];

    self.title = @"Lap Times";

    UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addTime:)];
    self.navigationItem.rightBarButtonItem = addButton;
    [addButton release];

    [self fetchRecords];

}

- (void)addTime:(id)sender {

    addTimeEvent *event = (addTimeEvent *)[NSEntityDescription insertNewObjectForEntityForName:@"addTime" inManagedObjectContext:self.managedObjectContext];
    [event setTimeStamp: [NSDate date]];

    NSError *error;
    if (![managedObjectContext save:&error]) {
        // This is a serious error saying the record could not be saved.
        // Advise the user to restart the application
    }

    [eventArray insertObject:event atIndex:0];
    [self.tableView reloadData];

}

- (void)fetchRecords {

    // Define our table/entity to use
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"addTime" inManagedObjectContext:self.managedObjectContext];

    // Setup the fetch request
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    [request setEntity:entity];

    // Define how we will sort the records
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"timeStamp" ascending:NO];
    NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];

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

    // Fetch the records and handle an error
    NSError *error;
    NSMutableArray *mutableFetchResults = [[managedObjectContext executeFetchRequest:request error:&error] mutableCopy];

    if (!mutableFetchResults) {
        // Handle the error.
        // This is a serious error and should advise the user to restart the application
    }

    // Save our fetched data to an array
    [self setEventArray: mutableFetchResults];

    [mutableFetchResults release];
    [request release];

}
另外,如果我使用自己的appdelegate(称为MyAppDelegate)

MyAppDelegate *tableController = [[MyAppDelegate alloc] initWithStyle:UITableViewStylePlain];
tableController.managedObjectContext = [self managedObjectContext];

self.navigationController = [[UINavigationController alloc] initWithRootViewController:tableController];
我得到以下错误:

Object cannot be set- either readonly property or no setter found

除了名称之外,RootViewController没有什么神奇之处。只要这些视图控制器配置正确,就可以对其进行重命名或与任何其他视图控制器进行交换。您可能需要使用RootViewController并相应地调整新的视图控制器


那就是说我不明白你想做什么。您可能想发布不起作用的代码。

我看不出您采用的原始方法有什么问题?您基本上是在应用程序委托中创建
managedObjectContext
,并通过赋值将其传递给
tableController

另一种方法是让viewController从应用程序委托“询问”managedObjectContext。因此,您仍然可以将CoreData方法放在AppDelegate中,并在希望获取上下文引用的地方使用以下方法。由于managedObjectContext是在请求时延迟加载的,因此只有在您第一次访问应用程序委托中的
managedObjectContext
方法时才会实例化它

AppDelegate *theDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
self.managedObjectContext = theDelegate.managedObjectContext;
PS1:显然,你需要用正确的应用程序名称替换AppDelegate


PS2:进行更改时出现错误的原因是没有可供CoreData使用的上下文。

如果
+entityForName:
出现异常,您应该在
+entityForName:
周围发布代码

如果我不得不猜测,我会说您的代码如下所示:

entity = [NSEntityDescription entityForName:@"Hello" 
                     inManagedObjectContext:managedObjectContext];
                                            ^^^^^^^^^^^^^^^^^^^^
这意味着您正在使用managedObjectContext,而不使用getter。如果第一次需要,getter会使用延迟加载来加载上下文。
我打赌managedObjectContext此时为零。使用调试器检查这一点

然后像这样更改行:

entity = [NSEntityDescription entityForName:@"Hello" 
                     inManagedObjectContext:self.managedObjectContext];
                                            ^^^^^^^^^^^^^^^^^^^^^^^^^
由于此调用,当包含关于rootviewcontroller的四行代码时,该代码起作用:

tableController.managedObjectContext = [self managedObjectContext];
                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^
如果为nil,则将创建上下文。延迟加载

[self-managedObjectContext]
self.managedObjectContext


但我的帖子中的所有内容都是猜测,因为您没有包括+entityForName:inManagedObjectContext:

的代码,实际上,他传递managedObjectContext的方法比向AppDelegate请求上下文要好。但只有当应用程序需要重构以使用不同的上下文进行插入时,人们才会意识到这一点。或者控制器是否将用于其他应用程序。我完全同意!让控制器请求上下文会在两者之间创建不必要的耦合。如果我使用上面的示例代码,我会得到以下错误:无法设置对象-找不到只读属性或设置器。您需要在视图控制器界面
@属性中为managedObjectContext创建属性(非原子,保留)NSManagedObjectContext managedObjectContext