Objective C中foo和foo_之间的区别

时间:2012-03-06 10:27:56

标签: objective-c

  

可能重复:
  How does an underscore in front of a variable in a cocoa objective-c class work?

interface您拥有foo_,然后是属性foo。在实施中,您有@synthesize foo = foo_foofoo_之间有什么区别。

4 个答案:

答案 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属性,差别不大 - 在任何一种情况下都会自动处理内存管理。