在 init 中设置的属性在 viewDidLoad 之后是 nil 吗?

Posted

技术标签:

【中文标题】在 init 中设置的属性在 viewDidLoad 之后是 nil 吗?【英文标题】:Properties set in init are nil right after in viewDidLoad? 【发布时间】:2012-09-20 19:56:11 【问题描述】:

我遇到了一个问题,派生类在其 initWithNibName 调用中设置了在超类中定义的属性,并且在调用 viewDidLoad 时,该属性再次神奇地未定义。它是这样的:

@interface BaseClassController : UIViewController



@property (copy, nonatomic) NSString *myString; // synthesized in the .m

在另一个文件中

@interface DerivedClassController : BaseClassController


及其实现:

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil

    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) 
        // Custom initialization
        NSLog(@"Setting MyString stuff");
        self.myString = @"Hi Mom";
        NSLog(@"Done setting myString");
    
    return self;


- (void)viewDidLoad

    NSLog(@"MyString is %@", self.myString); // output as (null)!!!
    [...]

根据 NSLog 的输出顺序是正确的,我知道 viewDidLoad 没有被首先调用:首先是 initWithNibName 方法,然后是 viewDidLoad。 viewDidLoad 每次都将 self.myString 报告为 (null)。但是,如果我将 myString 的初始化下移到 viewDidLoad,一切正常。为什么?我一定在这里遗漏了一些非常明显的东西..

编辑:

不确定这是否会有所不同,但 DerivedClassController 是导航控制器的根视图控制器,它以模态方式呈现(出于各种遗留原因)。

编辑 2:

代码在独立的 xcode 项目中按预期工作,导入到我最终需要使用它的项目时失败。

【问题讨论】:

信不信由你,同样的事情也发生在我身上。在init 中设置的属性在viewDidLoad 中为零。我尝试通过直接设置_myString 不使用合成访问器,但无济于事。这真的很难调试,因为它不是编程错误。 【参考方案1】:

您确定两次都从同一个控制器登录吗?比如,也许你在一个控制器上调用了initWithNibName:bundle:,但实际上在另一个控制器上调用了viewDidLoad

【讨论】:

【参考方案2】:

您有什么理由将其设置为复制吗?

尝试将属性设置为:

@property (nonatomic, strong) NSString *myString;

【讨论】:

复制是 ios 中的标准做法,这是 Big Nerd Ranch 的人的澄清:“一般来说,当你有一个属性指向具有可变子类的类的实例时(如 NSString 或 NSArray),创建对象的副本以指向而不是指向可能拥有其他所有者的现有对象更安全。”我仍然尝试变强,根据我所看到的并没有产生任何影响。 (顺便说一句,我不是那个投反对票的人)

以上是关于在 init 中设置的属性在 viewDidLoad 之后是 nil 吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 __init__ 中设置 python 属性

在 WebSocketServlet (Jetty WebSockets) 中访问在 HttpServlet 中设置的会话属性

BigQuery 没有获取在 java 中设置的属性

React - 访问在 useEffect 挂钩中设置的对象属性

按不同数组中设置的属性类型分隔项目

为啥在测试类中设置的 spring.profiles.active 在实际测试类的环境属性中不可用?