可能重复:
How does an underscore in front of a variable in a cocoa objective-c class work?目标C foo和foo_之间的差异
在interface
你有foo_
然后物业foo
。在实施中,你有@synthesize foo = foo_
。 foo
和foo_
之间有什么区别。
可能重复:
How does an underscore in front of a variable in a cocoa objective-c class work?目标C foo和foo_之间的差异
在interface
你有foo_
然后物业foo
。在实施中,你有@synthesize foo = foo_
。 foo
和foo_
之间有什么区别。
@synthesize foo = foo_
做,如果你让你不mistakingly惹其保持数只使用foo
这样做,编译器产生一个错误......
所以它是不太可能你会做_foo = something ;
比
foo = something; .
苹果希望你使用正确的setter方法.. 即self.foo =东西
@property SomeType *foo;
...
@synthesize foo = _foo;
创建@property
foo
,但其值存储在一个名为_foo
,不foo
伊娃。
也就是说,你将访问@property这样的:
yourObject.foo = someValue;
但在你的类实现,你将与_foo
,不foo
直接访问伊娃。正如Shubhank所说,当您改为使用@property
foo
代替时,这使得更难以意外地访问ivar _foo
。
如果您改为@synthesize foo;
,则@property
和伊娃将被命名为foo
。现在
,如果你明确宣布SomeType *_foo
被用来在诺维格的情况下@property
状提到,那么你需要做的@synthesize foo = _foo
,让编译器使用现有的伊娃_foo
而不是创建一个新的名为foo
。但是,即使您没有这样做,只要使用上面的两行代码就会让编译器自动声明ivar SomeType *foo
。
@synthesize指令告诉编译器为你声明的属性创建一个实例变量。
例如,如果你在.h文件中声明:
@property (nonatomic, retain) NSString *foo;
,并在你的。M档
@synthesize foo;
,这将产生一个私有的实例变量NSString *foo
,以及存取方法:
- (void)setFoo:(NSString *)foo;
- (NSString *)foo;
类中的代码可能看起来像
self.foo = @"bar"; // set through accessor - dot notation
[self setFoo:@"bar"]; // set through accessor - method notation
foo = @"bar"; // direct assignment
如果你不使用ARC,第二个例子将是不安全的,因为您正在分配自动释放字符串而不是保留字符串。这将被释放,你留下一个悬挂指针,访问时会崩溃。 您可能打算做的事是使用访问器,或者在分配时保留对象。 foo = [@"bar" retain];
通过在您.m文件声明不同的变量:
@synthesize foo = _foo;
你在做什么是告诉编译器创建变量私有实例NSString *_foo
代替。
我更喜欢这样做,因为当您直接访问实例变量而不是通过访问器方法访问实例变量时,下划线使得它更加清晰。特别是使用点符号时。如上面的例子中,代码如下所示:
_foo = @"bar"; // direct assignment
您可以立即看到你直接分配给伊娃,并应了解所涉及的内存语义。
声明:
@interface MyClass
{
MyOtherClass *foo_;
...
}
...
声明一个实例变量foo_
。声明:
@interface MyClass
@property (retain) MyOtherClass *foo;
...
声明了一个财产foo
。现在属性只是宣布两种方法 - 一个设置器(- (void) setFoo:(MyOtherClass *)obj
)和获取器(- (MyOtherClass *) foo
)。一个属性通常(并不总是)由一个实例变量支持,如果你有编译器通过使用@synthesize
为你写了setter &,那么支持变量(pre XCode 4.4)与属性名称相同。声明:
@synthesize foo = foo_;
指示编译器写的setter &吸气剂,但使用变量foo_
为后盾变量。
所以不同的是,foo
是一个属性的名称和使用,也可以在点标记(myClassInstance.foo
)或较不通常,通过直接调用setter或getter(例如[myClassInstance foo]
);而foo_
是一个实例变量的名称,可以使用箭头符号进行访问(例如,类内的self->foo_
或类外的myClassInstance->foo_
(如果可访问,前者可以删除self->
)。
如果您编写了自己的自定义setter/getter,或者如果您正在使用手动内存管理和合成保留或复制属性,则差异非常大,因为foo_
通过setter/getter因此自定义代码或合成内存管理代码。
在ARC或GC和综合保留/强/弱/复制属性下,差异不那么显着 - 在任何情况下,内存管理都将自动处理。