简体   繁体   English

在Objective-c中遇到属性问题

[英]Trouble with properties in Objective-c

I'm having trouble assigning an instance of a class to the following UITableViewController subclass: 我在将类的实例分配给以下UITableViewController子类时遇到麻烦:

@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: 我目前正在将MyClass的非null实例分配给MyTableViewController的实例,如下所示:

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

myTableViewController.myClass = nonNullInstanceOfMyClass;

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

[nonNullInstanceOfMyClass release];
[myTableViewController release];

The problem is that myClass is null in MyTableViewController's viewDidLoad . 问题是MyTableViewController的viewDidLoad中的myClass为null Why is this happening? 为什么会这样呢?

Edit #1 : I check that nonNullInstanceOfMyClass is not null by NSLogging it. 编辑#1 :我通过NSLogging检查nonNullInstanceOfMyClass是否不为null。

Edit #2 : Provided more code. 编辑#2 :提供了更多代码。 Also viewDidLoad seems to be called before I push the view controller (which could cause the problem... although it seems odd). 在推送视图控制器之前,似乎还调用了viewDidLoad (这可能会导致问题……尽管看起来很奇怪)。

Edit #3 : Fixed by moving self.tableView.delegate = nil; 编辑#3 :通过移动self.tableView.delegate = nil;固定self.tableView.delegate = nil; and self.tableView.dataSource = nil; self.tableView.dataSource = nil; from init to viewDidLoad . initviewDidLoad

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. 将视图控制器推到导航堆栈上时,不一定会调用viewDidLoad -在需要加载视图时会调用它。 So, for example, NSLog(@"%@", myTableViewController.view); 因此,例如, NSLog(@"%@", myTableViewController.view); would trigger viewDidLoad , and if you did this before assigning to the property, that would explain this behaviour. 会触发viewDidLoad ,如果您在分配给属性之前进行了此操作,则可以解释这种行为。

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. 从xib加载View时会触发viewDidLoad。

You have a couple options here. 您在这里有几个选择。

Easiest is the viewDidAppear: method 最简单的是viewDidAppear:方法

- (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: 或者,有viewWillAppear:

Another option is to have IB load the Class for you this way it is not null. 另一种选择是让IB以这种方式为您加载类,它不为null。 And will be available in viewDidLoad: 并将在viewDidLoad中可用:

Your MyClass will need to be a UIView. 您的MyClass必须是一个UIView。

You place a UIView (as a placeholder) into the TableViewController's View where you want it. 您将UIView(作为占位符)放置在TableViewController的所需视图中。

Then you set its class type in Interface Builder in the Identity Inspector under Custom Class. 然后,在“身份检查器”中“自定义类”下的“界面生成器”中设置其类类型。

Finally you drag a connection from the IBOutlet 最后,您从IBOutlet中拖动一个连接

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

to your Custom Class UIView in interface builder 到界面构建器中的自定义类UIView

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. 然后使用self.myClass,您的getter方法将为您创建一个。

EDIT: 编辑:

I added the =_myClass to the @synthesize to change the instance variable away from the property 我将= _myClass添加到@synthesize以将实例变量更改为远离属性

this way using myClass will generate an error and you will be forced to use self.myClass to get the property accessor. 这种使用myClass的方式将产生错误,并且您将被迫使用self.myClass来获取属性访问器。

Change the following line from: 将以下行更改为:

@property (nonatomic, retain) MyClass *myClass;

to: 至:

@property (nonatomic, assign) MyClass *myClass;

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

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