简体   繁体   English

除了RootViewController之外,如何在另一个视图上加载Core Data?

[英]How to load Core Data on another view besides the RootViewController?

I basically have the core data and the app working correctly except for the code in the AppDelegate. 我基本上有核心数据和应用程序正常工作,除了AppDelegate中的代码。 The code I'm having problems with is the following: 我遇到问题的代码如下:

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

}

I don't want to make the managedObjectContext the root view controller upon launch. 我不希望在启动时使managedObjectContext成为根视图控制器。 I'm wanting to make it another view controller. 我想让它成为另一个视图控制器。 However, if I change the classes to the view controller that I'm needing it for, it loads that view controller upon launch of the app, which is not what I want to do. 但是,如果我将类更改为我需要它的视图控制器,它会在启动应用程序时加载该视图控制器,这不是我想要做的。 I still want to launch the root view but I want to be able to load the core data context for my other view controller. 我仍然想要启动根视图,但我希望能够为我的其他视图控制器加载核心数据上下文。 I'm really confused on how to fix this issue. 我真的很困惑如何解决这个问题。 I've spent 2 days so far trying to find a way to fix this but no luck yet. 到目前为止,我花了两天时间试图找到解决这个问题的方法,但还没有运气。 Any help would be appreciated. 任何帮助,将不胜感激。

Also, if I leave out the following in the appdelegate didfinishlaunching: 另外,如果我在appdelegate中遗漏了以下内容:didfinishlaunching:

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

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

I get this error: 我收到此错误:

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '+entityForName: could not locate an NSManagedObjectModel for entity name 'Hello'

EDIT: Here is the entity code: 编辑:这是实体代码:

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

}

Also if I use my own appdelegate called MyAppDelegate 此外,如果我使用自己的appdelegate名为MyAppDelegate

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

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

I get the following error: 我收到以下错误:

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

There is nothing magical about the RootViewController beside the name. 名称旁边的RootViewController没什么神奇之处。 You can rename it or you can exchange it with any other View Controller as long as these View Controller are configured right. 您可以重命名它,也可以将其与任何其他View Controller交换,只要这些视图控制器配置正确即可。 You might want to take the RootViewController and adjust your new View Controller accordingly. 您可能希望采用RootViewController并相应地调整新的View Controller。

That said I don't understand what you want to do. 那说我不明白你想做什么。 You might want to post the code that doesn't work. 您可能希望发布不起作用的代码。

I can't see the problem with the original approach you are taking? 我无法看到你正在采取的原始方法的问题? You are basically creating the managedObjectContext in your App delegate and passing it on to the tableController via assignment. 您基本上是在App委托中创建managedObjectContext并通过赋值将其传递给tableController

The alternative way to go about it is to get your viewController to "ask" for the managedObjectContext from the App delegate. 另一种方法是让你的viewController从App委托“询问”managedObjectContext。 So you'd still have your CoreData methods placed in your AppDelegate and use the following where you want to get a reference to the context. 因此,您仍然可以将您的CoreData方法放在AppDelegate中,并使用以下内容来获取对上下文的引用。 Because the managedObjectContext is lazily loaded on request, it will only get instantiated the first time you access the managedObjectContext method in your app delegate. 由于managedObjectContext是在请求时延迟加载的,因此只有在您第一次访问应用程序委托中的managedObjectContext方法时才会实例化它。

AppDelegate *theDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
self.managedObjectContext = theDelegate.managedObjectContext;

PS1: obviously you need to replace AppDelegate with the correct name for your App. PS1:显然你需要用App的正确名称替换AppDelegate。

PS2: the reason you're getting the error when you make the changes is that there is no context available for CoreData to work with. PS2:您在进行更改时收到错误的原因是没有可供CoreData使用的上下文。

if you get an exception for +entityForName: you should post the code around +entityForName: . 如果你得到+entityForName:的异常+entityForName:你应该在+entityForName:周围发布代码+entityForName:

If I had to make a guess I would say that your code looks like this: 如果我不得不猜测我会说你的代码看起来像这样:

entity = [NSEntityDescription entityForName:@"Hello" 
                     inManagedObjectContext:managedObjectContext];
                                            ^^^^^^^^^^^^^^^^^^^^

this means you are using the managedObjectContext without the getter. 这意味着您使用的是没有getter的managedObjectContext。 And the getter uses lazy loading to load the context if it is needed for the first time. 如果第一次需要,getter使用延迟加载来加载上下文。
I bet managedObjectContext is nil at this point. 我认为此时managedObjectContext为零。 Use the debugger to check this out. 使用调试器来检查这一点。

And then change the line like this: 然后改变这样的行:

entity = [NSEntityDescription entityForName:@"Hello" 
                     inManagedObjectContext:self.managedObjectContext];
                                            ^^^^^^^^^^^^^^^^^^^^^^^^^

The code works when you include the four line about the rootviewcontroller because of this call: 由于此调用,当您包含关于rootviewcontroller的四行时,代码可以正常工作:

tableController.managedObjectContext = [self managedObjectContext];
                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^

this will create the context if it is nil. 如果它是零,这将创建上下文。 Lazy loading. 懒加载。

[self managedObjectContext] is the same as self.managedObjectContext [self managedObjectContext]self.managedObjectContext相同

but everything in my post is a guess because you didn't include the code around +entityForName:inManagedObjectContext: 但我的帖子中的所有内容都是猜测,因为您没有包含+ entityForName:inManagedObjectContext周围的代码:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM