【问题标题】:Objective-C Dot Syntax and InitObjective-C 点语法和初始化
【发布时间】:2011-03-10 04:38:47
【问题描述】:

我读过一些 sn-ps,其中提到你不应该在你的 init 或 dealloc 方法中使用点符号。但是,我似乎永远无法找出原因。一篇文章确实顺便提到它与 KVO 有关,但仅此而已。

@interface MyClass : NSObject {
    SomeObject *object_;
}
@property (nonatomic, retain) SomeObject *object;
@end

这个实现不好?

@implementation MyClass 

@synthesize object = object_;

- (id)initWithObject:(SomeObject *)object {
    if (self = [super init]) {
        self.object = object;
    }

    return self;
}
@end

但这很好吗?

@implementation MyClass 

@synthesize object = object_;

- (id)initWithObject:(SomeObject *)object {
    if (self = [super init]) {
        object_ = [object retain];
    }

    return self;
}
@end

在你的 init 中使用点符号有什么缺陷?

【问题讨论】:

  • 在第二个例子中你应该写 object_ = [object retain];
  • 已修复,快速编写示例的问题。 ;)

标签: objective-c syntax


【解决方案1】:

我听到的原因主要是由于您编写自己的 setter/getter 时出现的。当使用默认的 @synthesized 版本的方法时,它不会引起太大的问题。但是,当您编写自己的 setter 时,它通常会对您的课程产生副作用。在 init 中可能不需要这种副作用,或者如果它引用尚未创建的其他 ivars 甚至会导致问题。 dealloc 中的同样问题,如果你有副作用,它有可能爆炸。

【讨论】:

    【解决方案2】:

    首先,这不是点符号,而是你不应该使用的访问器。

    self.foo = bar;
    

    相同
    [self setFoo: bar];
    

    而且它们在 init/dealloc 中都不受欢迎。

    主要原因是因为子类可能会覆盖您的访问器并做一些不同的事情。子类的访问器可能假定一个完全初始化的对象,即子类的 init 方法中的所有代码都已运行。事实上,当您的 init 方法运行时,它们都没有。类似地,子类的访问器可能依赖于子类的 dealloc 方法已经运行。当您的 dealloc 方法正在运行时,这显然是错误的。

    【讨论】:

    • 谁会否决这个答案,请解释他们为什么这样做?
    猜你喜欢
    • 1970-01-01
    • 2021-10-16
    • 2015-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多