objective-C属性也定义为实例变量

时间:2018-02-28 18:20:11

标签: objective-c properties instance-variables

我已经定义了

@interface FooObject : NSObject
@property (nonatomic, readonly) Foo *foo;
@end

然后在实施中:

@implementation FooObject {
Foo *_foo;
...
}

但是,我的理解是创建属性

@property (nonatomic, readonly) Foo *foo;
接口中的

也会创建

_foo

所以我的问题是,这样做有什么好处,有什么可能的优势。

2 个答案:

答案 0 :(得分:1)

你问:

  

这样做有什么好处吗?

不,手动声明实例变量没有任何优势。事实上,这样做有一些缺点,因为你很容易误写ivar名称(或错误地使用@synthesize语句),最后是两个ivars,你手动创建的那个,以及是为你合成的。它只是介绍了可能的排印错误,导致难以诊断错误。

有几点需要注意:

  1. 这种手动定义ivars以支持你的属性的模式有点不合时宜,可以追溯到Objective-C编译器可以为你合成这些ivars之前。

    值得注意的是,如果您使用的是旧的Objective-C编译器(例如,特别是那些在非macOS平台上使用Objective-C或使用旧版Xcode的人),编译器可能会无法为您自动合成这些ivars,您必须手动执行此操作。尽管如此,您仍然使用@synthesize指令让编译器为您执行此操作,而不是手动声明ivar。只有当你使用的是一个非常古老的编译器时,才需要手动声明ivar。

  2. 如果您自己实现所有访问器方法(即只读取只读取属性的getter或者读写属性的getter和setter),编译器将不会为您合成ivar。据推测,如果您正在编写自己的存取方法,那么您可能会让那些人做一些事情而不是与传统的ivar交互,因此它不会为您合成伊娃。

    在这种情况下,如果您需要,您必须自己手动合成ivar。例如,考虑这个类:

    @synthesize

    如果您同时实施两个访问者:

    @interface Foo: NSObject
    @property (nonatomic) NSInteger bar;
    @end
    

    然后你必须自己在- (void)setBar:(NSInteger)bar { // do something, and then update ivar _bar = bar; } - (NSInteger)bar { // do something, and then retrieve ivar return _bar; } 内手动合成ivar:

    @implementation

    注意,我没有手动定义@synthesize bar = _bar; ivar,但我仍然让编译器这样做,但我必须使用_bar指令手动启动它。

    我上面的例子是一个读写属性。对于您已实施自己的自定义getter的只读属性,同样的问题也适用。

    显然,如果你没有实现自定义访问器方法(我们通常不会这样做),你就不必手动合成ivar。只需定义@synthesize,即可完成。

答案 1 :(得分:0)

没有优势。只需删除Trial Number Measurement 1 0.1 1 0.5 1 0.7 1 0.3 1 0.2 2 0.2 2 0.4 2 0.5 ... ... 即可。在这种情况下,这是多余的。