Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is my IBOutlet being released under ARC?

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.

like image 836
John Gallagher Avatar asked Jun 19 '12 11:06

John Gallagher


3 Answers

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

like image 51
Adrian Ancuta Avatar answered Nov 07 '22 17:11

Adrian Ancuta


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!

like image 35
Thermometer Avatar answered Nov 07 '22 17:11

Thermometer


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.

like image 1
Bill Burgess Avatar answered Nov 07 '22 17:11

Bill Burgess