【问题标题】:NSDate ivar become <not an Objective-C object>?NSDate ivar 变成 <不是一个 Objective-C 对象>?
【发布时间】:2013-02-24 08:24:28
【问题描述】:
- (id)initWithCoder:(NSCoder *)aDecoder
{
   dueDate = [NSDate date];

}

- (void)viewDidLoad
{
    [super viewDidLoad];

    NSDateFormatter *formatter = [[[NSDateFormatter alloc] init] autorelease];
    [formatter setDateStyle:NSDateFormatterShortStyle];
    [formatter setTimeStyle:NSDateFormatterShortStyle];
    self.lbDueDate.text = [formatter stringFromDate:dueDate];
}

在初始化方法中我声明了dueDate = [NSDate date]。但是当我调试时,在这一行

    self.lbDueDate.text = [formatter stringFromDate:dueDate];

输出:(NSDate *)dueDate = 0x0c497390 那么发生了什么?

【问题讨论】:

  • 当对象未正确保留时可能会发生这种情况,这是 ARC 项目吗?如果不是 ARC,您应该使用 dueDate = [[NSDate date] retain];
  • dueDate 声明为@property 并使用self.dueDate 而不是dueDate。这应该在 ARC/非 ARC 中修复它。
  • 和@property 应该是retain/strong(非ARC/ARC)...
  • 你能解释一下为什么如果使用 self.dueDate 而不是 dueDate 问题就解决了吗?在这种情况下,ivar 和属性之间有什么区别?

标签: ios objective-c nsdate


【解决方案1】:

这意味着该对象已被-dealloced(除非它是nil)。因此,与 Zombies 一起运行并更频繁地向它发送消息——在运行静态分析器并查看您的代码之后。

源中有一个问题:dueDate = [NSDate date]; 应该是dueDate = [[NSDate date] copy];。另一个问题是您在-initWithCoder: 的实现中没有通过超类的指定初始化程序进行调用。

【讨论】:

  • 为什么需要通过超类的指定初始化器来调用?
  • @DungProton 你在-initWithCoder: 中调用它,因为-initWithCoder: 是一个初始化器。与任何初始化程序实现相同(即-init)。因此,如果超类采用NSCoding,则应编写self = [super initWithCoder:pCoder],否则使用适当的指定初始化程序(self = [super init] 很常见)。如果没有这一步,你应该假设基类没有正确初始化。
  • 我只知道我必须写self = [super initWithCoder:pCoder],但我真的真的不知道为什么我必须这样做。你能和我分享任何与此相关的文件或帖子吗?非常感谢你^^
  • @DungProton 基本初始化/破坏对称性。它包含在相关指南中; 存档和序列化编程指南。两个原因:a) 所以基类也可以反序列化它已序列化的任何信息/状态,b) 因为基类的实现可能返回一个分配,而不是作为命名隐式参数 self 传递的分配。这意味着序列化子类的状态是子类的责任(好);如果你重写超类的实现,你必须调用正确的初始化器,这样超类也可以正确地反序列化自己
  • (cont) 再一次,如果您的班级是第一个采用 NSCoding 的班级,您只需在 -initWithCoder: 的实现中检查指定的初始化程序之一。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-08
  • 1970-01-01
  • 2012-03-14
  • 2012-10-17
  • 1970-01-01
  • 2011-07-30
相关资源
最近更新 更多