Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 什么';当财产存在时,ivar的目的是什么?_Objective C_Properties - Fatal编程技术网

Objective c 什么';当财产存在时,ivar的目的是什么?

Objective c 什么';当财产存在时,ivar的目的是什么?,objective-c,properties,Objective C,Properties,下面的代码在编译或运行时都不会抱怨没有nameivar。那么,为什么ivar和@property/@synthesis如此常见呢 @interface PropTest : NSObject { } @property (retain) NSString *name; @end @implementation PropTest @synthesize name; @end int main (int argc, const char * argv[]) { NSAutoreleasePo

下面的代码在编译或运行时都不会抱怨没有
name
ivar。那么,为什么ivar和
@property/@synthesis
如此常见呢

@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;
}
此代码打印

Hello, World!
事实上,如果我访问
p->name
,我会得到一个警告:

warning: instance variable 'name' is @private; this will be a hard error in the future
这表示如果不存在ivar,则会为我创建一个ivar

如果这是真的,那么手动创建ivar的意义何在(忽略显而易见的一点,即有时不使用g/setter访问器是有正当理由的)


或者换一种方式问,我应该只在需要绕过访问器时为属性创建ivar吗?

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

eman的答案总体上是正确的,但即使在新的运行时,仍有一个理由要声明IVAR:Apple不鼓励在init和dealloc方法中使用合成访问器。从本质上讲,getter和setter除了设置变量外,还可以产生副作用。特别是,它们可以触发KVO通知。有了ivar可以通话,您只需发送
release
即可完成。但是,如果您只有一个属性,那么您唯一的选择就是设置它,并希望您避免任何不幸的交互


老实说,我不确定这在实践中有多大问题。我只是迷信地避开了它,尽管我私下怀疑它在大多数情况下都会引起问题。但苹果公司在文档中确实强调了这一点,因此我认为有一些理由值得关注。

有两个不太好但必要的理由确保属性由IVAR备份:

  • 由于某些原因,XCode调试器不会显示没有显式声明相应IVAR的属性
  • 在我看来,在某些情况下,在没有ivar的情况下使用@property可能会隐藏其他ivar,从而导致编译错误(请参阅)

  • 除非我在这里遇到了一些错误,否则我认为在没有显式ivar的情况下使用@property可能会带来不便。

    您仍然可以使用合成ivar直接访问ivar(有一个错误您无法访问,但我很确定它现在已经修复),所以这不是问题。@eman:IIRC他们正在计划修复,但除非您使用的是预发布的Xcode版本。我认为正如Cris所说,不声明IVAR存在一些问题。调试是我经常遇到的问题。