开发者

Trouble with properties in Objective-c

开发者 https://www.devze.com 2023-04-07 01:31 出处:网络
I\'m having trouble assigning an instance of a class to the following UITableViewController subclass:

I'm having trouble assigning an instance of a class to the following UITableViewController subclass:

@interface MyTableViewController : UITableViewController </*usual protocols*/>
@property (nonatomic, retain) MyClass *myClass;
@end

I'm currently assigning a non-null instance of MyClass to an instance of MyTableViewController like this:

MyTableViewController *myTableViewController = [[MyTableViewController alloc] init];
MyClass *nonNullInstanceOfMyClass = [[MyClass alloc] init];

myTableViewController.myClass = nonNullInstanceOfMyCl开发者_如何学Cass;

[self.navigationController pushViewController:myTableViewController animated:YES];

[nonNullInstanceOfMyClass release];
[myTableViewController release];

The problem is that myClass is null in MyTableViewController's viewDidLoad. Why is this happening?

Edit #1: I check that nonNullInstanceOfMyClass is not null by NSLogging it.

Edit #2: Provided more code. Also viewDidLoad seems to be called before I push the view controller (which could cause the problem... although it seems odd).

Edit #3: Fixed by moving self.tableView.delegate = nil; and self.tableView.dataSource = nil; from init to viewDidLoad.


Are you doing anything between instantiating the view controller and assigning to the property? viewDidLoad doesn't necessarily get called when you push the view controller onto the navigation stack - it gets called whenever it needs to load the view. So, for example, NSLog(@"%@", myTableViewController.view); would trigger viewDidLoad, and if you did this before assigning to the property, that would explain this behaviour.

Could you post actual code instead of an approximation please? There could be important details you are leaving out.


viewDidLoad is fired when the View is loaded from xib.

You have a couple options here.

Easiest is the viewDidAppear: method

- (void)viewDidAppear:(BOOL)animated
{
    // Handle what you want for when your view has become visible. 
    // This may happen more then once. So a flag for the first time will
    // give you a sufficient Limit for Initialization
}

alternatively there is the viewWillAppear:

Another option is to have IB load the Class for you this way it is not null. And will be available in viewDidLoad:

Your MyClass will need to be a UIView.

You place a UIView (as a placeholder) into the TableViewController's View where you want it.

Then you set its class type in Interface Builder in the Identity Inspector under Custom Class.

Finally you drag a connection from the IBOutlet

@property (nonatomic, retain) IBOutlet MyClass *myClass;

to your Custom Class UIView in interface builder

Then when Interface builder initializes your class it will populate that property with a blank instance of that class.

A third option would be a lazy load property

Here is how I do lazy load

//we will take for granted that your @property is in the header
//and the following Synthesize is on the class
@synthesize myClass=_myClass; // setting instance variable to avoid confusion 
- (MyClass*) myClass
{
    if (_myClass == nil) _myClass = [[MyClass alloc] init];//Create a default instance and retain it
    return _myClass;
}

then you use self.myClass and your getter method will create one for you.

EDIT:

I added the =_myClass to the @synthesize to change the instance variable away from the property

this way using myClass will generate an error and you will be forced to use self.myClass to get the property accessor.


Change the following line from:

@property (nonatomic, retain) MyClass *myClass;

to:

@property (nonatomic, assign) MyClass *myClass;
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号