【问题标题】:iOS5: Confusion with loadview and init and instance variablesiOS5:与 loadview 和 init 和实例变量混淆
【发布时间】:2011-12-27 21:11:07
【问题描述】:

我是 iOS5 和故事板的新手。

我注意到,如果我在我的 viewcontroller .h 文件中声明一个实例变量并在我的 viewcontroller 的 .m 文件的 init 中设置值,当显示 viewcontroller 的视图时,我的实例变量在 viewDidLoad 中显示为 null。为了让我获得我的变量,我需要在 viewDidLoad 中执行 [self init]。我的问题是:

@interface tableViewController : UITableViewController
{
NSMutableArray *myvariable;
}
@end

@implementation tableViewController
-(id)init
{
myvariable = [[NSMutableArray alloc]initWithObjects:@"Hi2",@"Yo2",@"whatsup2", nil];
}

- (void)viewDidLoad
{
NSLog(@"%@",myvariable); // DISPLAYS NULL
[super viewDidLoad];
}
  1. 当我在 .h 和 .m 文件中声明和实现时,为什么我的变量在 viewdidLoad 中不可用?
  2. 如果是这种情况,viewDidLoad 或 viewWillAppear 是为 viewcontroller 加载数据的常用位置吗?
  3. 看起来即使您实例化了一个视图控制器并调用了 init 函数,viewDidLoad 也不一定有要显示的变量。
  4. 为我的视图控制器加载模型(数据)的正确位置/方法在哪里?

提前致谢

【问题讨论】:

    标签: iphone xcode ios5 storyboard


    【解决方案1】:

    所以回答你的第一个问题,在这种情况下调用的初始化程序是 initWithCoder:,而不是 init。因此,如果您将 NSArray 初始化移动到 initWithCoder: 您应该会发现它在视图加载之前可用。

    别忘了你也必须调用你的超类的初始化器。所以这样的模式会起作用:

    -(id)initWithCoder:(NSCoder *)aDecoder {
    
        if ((self = [super initWithCoder:aDecoder])) {
    
            // initialize what you need here
        }
    
        return self;
    
    }
    

    您还将在 initWithCoder: 之后调用 awakeFromNib 并且在所有插座都已连接之后,因此如果您的初始化依赖于正在填充的插座,则有有机会在那里进行初始化。

    当然还有 viewDidLoad 和 viewWillAppear:。我不知道对“正确”的使用方法有一般的答案(问题 2 和 4)。这取决于您拥有多少数据,需要多久刷新一次,以及加载需要多长时间。我的观点是,这是针对每个案例做出的决定。

    对于第 3 个问题,你有一个例子来说明你在那里看到的吗?初始化器肯定会在 viewDidLoad 之前被调用。诀窍是知道调用了哪个初始化程序。

    请记住,viewDidLoad 在视图控制器的生命周期内可能会被多次调用。所以要为此做好准备。当然,viewWillAppear: 更有可能在视图控制器的生命周期内被多次调用。

    希望对您有所帮助。

    【讨论】:

    • 嗨,Firoze,感谢您的回答。 initWithCoder 绝对是正确调用的函数,是否所有视图控制器总是调用 initWithCoder。将我的变量实例化放入 initWithCoder、initWithNibName 和 init 有什么区别?这是否意味着当我执行 SomeViewController *test = [[SomeViewController alloc] init]; 时,也会调用 initWithCoder?
    • awakeFromNib 是这种初始化 IMO 的更好地方。要回答这个问题 - 如果您从 nib 文件创建对象 - 使用 awakeFromNib,如果您在代码中创建对象 - 使用 init。
    • 好吧,不,@sunwukong,我不是建议你自己调用 initWithCoder。该框架将在取消归档您在情节提要中拥有的任何视图控制器时调用该方法。所以如果你想在故事板中初始化一个视图控制器,你需要重写 initWithCoder: 和/或 awakeFromNib。
    • @sunwukong,澄清一下,如果您自己调用 init,那么您的 init 当然会被调用,正如您所期望的那样。但关键是故事板/笔尖加载机制不调用init,它调用initWithCoder。然后它连接您的插座并调用 awakeFromNib。希望这很清楚。
    • 这正是我所需要的。再次感谢 Firoze。
    猜你喜欢
    • 1970-01-01
    • 2015-07-01
    • 2014-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-16
    相关资源
    最近更新 更多