6

The Problem

An IBOutlet is released before I have a chance to use it.

What I Want

I want to access a navigation controller from my app delegate so I can reload a table view.

My Setup

I have:

  • A Main.xib that's set as my main interface in target settings
  • An IBOutlet to the navigation controller as an ivar on my app delegate
  • This IBOutlet hooked up to the correct navigation controller in Main.xib
  • App Delegate is instantiated in the xib but not set as File's Owner

I'm using ARC, Xcode 4.3.2 and iOS5.1

What I've Tried

  • Changing deployment target
  • Putting a break point on dealloc for the navigation controller, app delegate - they're never called
  • Reading everything I can find on ARC and IBOutlets - nothing seems to contradict what I'm doing
  • Creating a fresh project with just a the minimum classes required - I see exactly the same problem

Code

KPAppDelegate.h

@interface KPAppDelegate : UIResponder <UIApplicationDelegate> {
    IBOutlet  KPBrowseExpensesNavigationController *nc;
}

@property (strong) IBOutlet KPBrowseExpensesNavigationController *nc;

KPAppDelegate.m

@implementation KPAppDelegate

@synthesize nc;

-(void)setNc:(KPBrowseExpensesNavigationController *)nc_ {
    nc = nc_; // This gets called on view load and nc gets set.
}

...snip...

// This is called about 5 seconds after app startup
-(void)objectLoader:(RKObjectLoader *)objectLoader didLoadObjects:(NSArray *)objects {
        // By the time we get here, nc is nil.
        UITableViewController *tvc = [[nc viewControllers] objectAtIndex:0];
        [[tvc tableView] reloadData];
}

@end

UPDATE

I must be doing something really silly here. Even an incredibly simple project still shows this problem. See link below.

Download a simple test project that shows the problem.

4 Answers4

2

is your outlet from the Interface Builder set as an KPBrowseExpensesNavigationController type? If not it is not going to create the connection between your nib and ViewController.

You should set its Custom Class as KPBrowseExpensesNavigationController in the Identity Inspector

Adrian Ancuta
  • 1,036
  • 9
  • 16
2

In Window nib, set the FilesOwner Class as UIApplication and then point it's delegate from Outlets to the AppDelegate object. This is what is wrong in your project example.

Adrian Ancuta
  • 1,036
  • 9
  • 16
  • You, sir, are brilliant. This did occur to me, but since the delegate seemed to be getting executed, I thought this wouldn't be the issue. I wish I'd tried this 5 hours ago...! Thanks again. – John Gallagher Jun 19 '12 at 15:04
  • no problem, it is easier to figure it out on a project than of some line of codes here. So you did very good by explaining with an example of a project:) – Adrian Ancuta Jun 19 '12 at 18:50
1

I am not sure why you declare it as a property & a non-property. I should do something like this:

@interface KPAppDelegate : UIResponder <UIApplicationDelegate> 

@property (nonatomic, strong) IBOutlet KPBrowseExpensesNavigationController *nc;

And in your implementation:

@implementation KPAppDelegate

@synthesize nc = _nc; // So you don't accidentally use nc

...snip...

// This is called about 5 seconds after app startup
-(void)objectLoader:(RKObjectLoader *)objectLoader didLoadObjects:(NSArray *)objects {
        // By the time we get here, nc is nil.
        UITableViewController *tvc = [[**self.nc** viewControllers] objectAtIndex:0];
        [[tvc tableView] reloadData];
}

@end

Hope this helps!

Thermometer
  • 2,567
  • 3
  • 20
  • 41
1

I didn't see where you alloc your nav controller. Just declaring the property won't assign any value to it, so it would be nil. In you -didFinishLaunchingWithOptions in the app delegate, set your alloc/init statement. Everything else looks fine.

KPBrowseExpensesNavigationController *nc = [[KPBrowseExpensesNavigationController alloc] init];

If you have a custom init, you can use that too, but just make sure to set it up before you try and use it.

Bill Burgess
  • 14,054
  • 6
  • 49
  • 86