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

问题描述 投票:2回答:2

我已经定义了

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

然后在实施中:

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

但是,我的理解是创造财产

@property (nonatomic, readonly) Foo *foo;

在界面中,也创建

_foo

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

objective-c properties instance-variables
2个回答
1
投票

你问:

这样做有什么好处吗?

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

几点需要注意:

  1. 这种手动定义ivars以支持你的属性的模式有点不合时宜,可以追溯到Objective-C编译器可以为你合成这些ivars之前。 值得注意的是,如果您使用旧的Objective-C编译器(例如,特别是那些在非macOS平台上使用Objective-C或使用旧版本的Xcode进行实验),编译器可能无法自动合成这些ivars你,你必须手动这样做。尽管如此,你还是会使用@synthesize指令让编译器为你做这件事,而不是手动声明ivar。只有当你使用的是一个非常古老的编译器时才会引入@synthesize指令,你需要手动声明ivar。
  2. 如果您自己实现所有访问器方法(即只读取只读取属性的getter或读取和写入属性的getter和setter),编译器将不会为您合成ivar。据推测,这个想法是,如果你正在编写自己的存取方法,那么除了与传统的ivar交互之外,你可能会做其他事情,所以它不会为你合成ivar。 在这种情况下,如果需要,您必须自己手动合成ivar。例如,考虑这个类: @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; } 然后你必须自己在@implementation内手动合成ivar: @synthesize bar = _bar; 注意,我没有手动定义一个_bar ivar,但我仍然让编译器这样做,但我不得不用@synthesize指令手动启动它。 我上面的例子是一个读写属性。同样的问题适用于您已实现自己的自定义getter的只读属性。 显然,如果你没有实现自定义访问器方法(我们通常不这样做),你就不必手动合成ivar。只要定义@property,你就完成了。

0
投票

没有优势。只需删除Foo *_foo;。在这种情况下,这是多余的。

© www.soinside.com 2019 - 2024. All rights reserved.