当我提供getter和setter时,为什么需要编写@synthesize?

时间:2012-10-16 15:38:22

标签: objective-c properties synthesize

所以属性的自动合成非常棒。但是,当您同时提供getter和setter时,会出现错误。

@property (strong, nonatomic) NSArray *testArray;

- (NSArray *)testArray {
    return _testArray;
}

- (void)setTestArray:(NSArray *)testArray {
    _testArray = testArray;
}

错误:Use of undeclared identifier '_testArray'

添加@synthesize testArray = _testArray;解决了这个问题。我只是想知道为什么会这样?

3 个答案:

答案 0 :(得分:8)

当您同时提供getter和setter时,通常根本不需要实例变量,即只需转发这些消息或将数据存储在其他位置。

只要缺少其中一个,就需要使用ivar来合成该功能。

如果我没记错的话,对于只读属性,模拟假设也是如此。

答案 1 :(得分:8)

在最近的编译器/运行时,使用

@synthesize testArray = _testArray;

编译器创建

  • _testArray ivar,如果它还不存在;
  • 一个testArray方法,如果你没有实现它;
  • setTestArray:方法,如果您尚未实施。

如果您使用

@synthesize testArray;

编译器创建testArray ivar(如果它尚不存在),而不是_testArray

如果您不使用@synthesize并依赖自动合成,则只有在(两者都必须适用)时才会创建_testArray ivar

  • _testArray尚不存在;
  • 至少合成了一种方法(readonly的getter,readwrite的getter和/或setter。

在您的示例中,您已实现了所有方法,因此自动合成不会合成任何方法,因此它不会创建ivar。您可以自己声明_testArray ivar,也可以像使用的那样使用显式合成。

答案 2 :(得分:-1)

我做了一些测试:

根据最近的Objective-c约定,您不需要合成属性。

如果你这样做

@property (strong, nonatomic) Business* theBiz;

iOs将自动创建一个名为_theBiz的私有ivar变量;

如果你只实现一个getter或setter,它似乎工作正常:

-(void)setTheBiz:(Business *)theBiz
{
    _theBiz = theBiz;
}

但是,如果你声明BOTH,即使其中一个只是空函数,你也会遇到编译错误。

-(void)setTheBiz:(Business *)theBiz
{
    _theBiz = theBiz;
}

-(Business *) theBiz
{

}

当你实现BOTH getter和setter时,你会得到一个编译错误,说这不是_theBiz。

可以通过添加以下内容轻松解决:

@synthesize theBiz = _theBiz;

但是,这打败了Objective-c这个令人敬畏的新功能的全部要点。

我想知道这是设计还是我遗漏了一些东西。苹果有什么用?

我最好的猜测是这是一个错误。

Guillaume的回答没有解决这个问题。

他说那个

  

至少已经合成了一种方法

如果设置了一个getter或setter,那么似乎已经创建了_theBiz。设置两者时,不再创建它,而且必须是错误。事实上,根本不需要设置任何东西,仍然会创建ivar。

解决这个问题的唯一方法是明确地做

@synthesize theBiz = _theBiz;