0

I've used the following code to pass a context to a ViewController in the pass without issue but for some reason it is behaving differently for this project.

  1. User performs an action
  2. I load the ViewController like so:

    ProjectListViewController *projectListViewController = [[ProjectListViewController alloc] init]; 
    projectListViewController.context = [self context];
    [self.view addSubview:[projectListViewController view]];
    
  3. In the viewDidLoad method I have the following:

    if (_context != nil) {
    
       NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
       NSEntityDescription *entity = [NSEntityDescription
            entityForName:@"Project" inManagedObjectContext:_context];
    
       [fetchRequest setEntity:entity];
       NSError *error;
       self.projects = [_context executeFetchRequest:fetchRequest error:&error];
    }
    
  4. It turns out _context is nil.

Did a debug, this is what I found.

The ViewDidLoad method is run before it even gets to the line [self.view addSubview:[projectListViewController view]]; therefore the context is not set.

But if I remove the init from the view declaration then the projectListViewController.context = [self context]; gets run and so the context is not nil.

Am I incorrect to think that the ViewDidLoad should not run before the addSubview is called?

Is there a better way to pass the context to the ViewController?

RK-
  • 12,099
  • 23
  • 89
  • 155
Allfocus
  • 293
  • 1
  • 5
  • 14

2 Answers2

0

-viewDidLoad will be not be called until the view is needed - that is until it needs to be displayed and after it has loaded. I would usually put a convenience method in the app delegate or a singleton that would return the context.

Morrowless
  • 6,856
  • 11
  • 51
  • 81
0

Based on Apple's documentation.

The load cycle is triggered when the view controller’s view property is accessed and the view is not currently in memory.

So here is what happens, my ViewController calls the initWithNibName. The next method it calls is ViewDidLoad as a result of the ViewController being accessed.

This means the view was actually loaded just not added yet, and so the passing of the _context happens after the ViewDidLoad event making _context nil.

Simple solution is if you don't need the initWithNibName method to make any customisations then then remove it that way the View Controller is not accessed and so the ViewDidLoad is not called before the passing of the context and adding of it as a subView.

I will be using the solution proposed by Philip, just wanted to understand why.

Allfocus
  • 293
  • 1
  • 5
  • 14