我已经定义了
@interface FooObject : NSObject
@property (nonatomic, readonly) Foo *foo;
@end
然后在实施中:
@implementation FooObject {
Foo *_foo;
...
}
但是,我的理解是创建属性
@property (nonatomic, readonly) Foo *foo;
接口中的也会创建
_foo
所以我的问题是,这样做有什么好处,有什么可能的优势。
答案 0 :(得分:1)
你问:
这样做有什么好处吗?
不,手动声明实例变量没有任何优势。事实上,这样做有一些缺点,因为你很容易误写ivar名称(或错误地使用@synthesize
语句),最后是两个ivars,你手动创建的那个,以及是为你合成的。它只是介绍了可能的排印错误,导致难以诊断错误。
有几点需要注意:
这种手动定义ivars以支持你的属性的模式有点不合时宜,可以追溯到Objective-C编译器可以为你合成这些ivars之前。
值得注意的是,如果您使用的是旧的Objective-C编译器(例如,特别是那些在非macOS平台上使用Objective-C或使用旧版Xcode的人),编译器可能会无法为您自动合成这些ivars,您必须手动执行此操作。尽管如此,您仍然使用@synthesize
指令让编译器为您执行此操作,而不是手动声明ivar。只有当你使用的是一个非常古老的编译器时,才需要手动声明ivar。
如果您自己实现所有访问器方法(即只读取只读取属性的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
... ...
即可。在这种情况下,这是多余的。