当一个财产存在时,ivar的目的是什么?

nic*_*bot 19 properties objective-c

关于没有nameivar ,以下内容不会在编译或运行时抱怨.那么为什么看到ivar @property/@synthesize.

@interface PropTest : NSObject
{
}
@property (retain) NSString *name;
@end

@implementation PropTest
@synthesize name;
@end

int main (int argc, const char * argv[]) {
  NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
  PropTest *p = [[PropTest new] autorelease];
  p.name = @"Hello, World!";
  NSLog(@"%@",p.name);
  [pool drain];
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

此代码打印

Hello, World!
Run Code Online (Sandbox Code Playgroud)

事实上,如果我访问p->name,我会收到警告:

warning: instance variable 'name' is @private; this will be a hard error in the future
Run Code Online (Sandbox Code Playgroud)

这表示如果不存在ivar就会为我创建.

如果这是真的,那么手动创建ivar有什么意义(忽略显而易见的,有时候有理由不使用g/setter访问器)?

或者换句话说,当我需要绕过访问者时,我是否应该为物业创建一个ivar?

sho*_*sti 19

合成的ivars(不能手动声明ivars的能力)是新的Objective-C运行时的一个特性,它仍然没有在所有系统上使用.对于32位Mac(以及直到最近的iPhone模拟器),您必须手动声明ivars.如果您只针对具有新运行时的系统,则没有理由手动声明ivars.


Chu*_*uck 8

eman的答案总的来说是正确的,但即使在新的运行时也有一个原因仍然是声明ivars:Apple不鼓励init和dealloc方法中的合成访问器.基本上,除了设置变量之外,允许getter和setter具有副作用.特别是,它们可以触发KVO通知.使用ivar进行交谈,您可以发送release并完成它.但如果你拥有的只是一个财产,那么你唯一的选择就是设置它并希望你避免任何不幸的互动.

老实说,我不确定这在实践中有多大问题.我只是迷信地避免它,尽管我暗地怀疑它会在大多数情况下引起问题.但苹果确实在文档中指出了这一点,所以我认为有一些理由需要关注.

  • 直接访问合成的ivars从3.2.4开始工作. (6认同)

Cri*_*ris 7

两个不太好但必要的理由确保属性由ivars支持:

  1. 由于某种原因,XCode调试器不显示没有显式声明的相应ivars的属性.
  2. 在我看来,在某些情况下使用没有ivar的@property可以隐藏其他ivars,导致编译错误(请参阅为什么子类@property没有相应的ivar隐藏超类ivars?)

除非我在这里得到了几根棍子的错误结果,否则我认为在没有明确的ivars的情况下使用@property可能会导致不方便的烦恼.