可能重复:
How does an underscore in front of a variable in a cocoa objective-c class work?
在interface
您拥有foo_
,然后是属性foo
。在实施中,您有@synthesize foo = foo_
。 foo
和foo_
之间有什么区别。
答案 0 :(得分:1)
@synthesize foo = foo_
如果仅使用foo
,会使编译器生成错误
这样做是为了让你不会误解其保留计数...
所以你不太可能做_foo = something ;
<强>大于强>
foo = something; .
Apple希望您使用正确的setter方法.. 即self.foo =某事
答案 1 :(得分:1)
@property SomeType *foo;
...
@synthesize foo = _foo;
创建@property
foo
,但其值存储在名为_foo
的ivar中,而不是foo
。
也就是说,您可以像这样访问@property:
yourObject.foo = someValue;
但是在您的课程实施中,您可以使用_foo
直接访问ivar,而不是foo
。正如Shubhank所说,当您想要使用_foo
@property
而不是意外地访问ivar foo
时。
如果您改为@synthesize foo;
,则@property
和ivar都会被命名为foo
。
现在,如果您明确声明SomeType *_foo
用于@property
- 就像Novarg提到的那样 - 那么您需要执行@synthesize foo = _foo
以使编译器使用现有的ivar _foo
而不是创建一个名为foo
的新ivar。但是,即使您没有这样做,只需使用上面两行代码就会使编译器自动声明ivar SomeType *foo
。
答案 2 :(得分:0)
@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
你可以立即看到你直接分配给一个ivar,并且应该知道所涉及的内存语义。
答案 3 :(得分:0)
宣言:
@interface MyClass
{
MyOtherClass *foo_;
...
}
...
声明实例变量 foo_
。声明:
@interface MyClass
@property (retain) MyOtherClass *foo;
...
声明属性 foo
。现在,属性只是声明两种方法的简写 - setter (- (void) setFoo:(MyOtherClass *)obj
)和 getter (- (MyOtherClass *) foo
)。一个属性通常(并不总是)由实例变量支持,如果你有编译器写入setter&amp;使用@synthesize
为您获取getter,然后支持变量(pre XCode 4.4)与该属性具有相同的名称。声明:
@synthesize foo = foo_;
指示编译器编写setter&amp; getter但要使用变量foo_
作为后备变量。
所以区别在于foo
是属性的名称,并以点表示法(myClassInstance.foo
)使用,或者通常直接调用setter或getter(例如{{1})。 });虽然[myClassInstance foo]
是实例变量的名称,但是使用箭头符号进行访问(例如,类中为foo_
,或者如果可访问则在类外部self->foo_
,前者可以删除myClassInstance->foo_
})。
如果您已经编写了自己的自定义setter / getter,或者如果您正在使用手动内存管理并合成保留或复制属性,则通过setter / getter传递差异非常大self->
,因此自定义代码或合成的内存管理代码。
在ARC或GC下,合成了retain / strong / weak / copy属性,差别不大 - 在任何一种情况下都会自动处理内存管理。