2013-10-26 53 views

回答

2

obj->foo语法访问的objobj.foo访问属性(由@property定义)的ivar foo。主要区别在于obj->foo不使用任何getter/setter并直接写入ivar。

例如,如果你像这样定义

@property (atomic, strong, readonly) SomeClass *foo; 
财产

现代的Objective-C编译器会自动创建伊娃_foo并为你的财产foo(无需申报伊娃和@synthesize荷兰国际集团的属性。

obj.foo将自动使用atomic getter和将财产readonly(即没有setter)使用伊娃语法obj->_foo,您正在阅读的属性非原子盟友(!),你甚至可以写它(记住,该属性是readonly!)。

通常很简单:始终使用属性语法,除了在initdealloc之外,您使用的是ivar语法。很明显,当你实际上实现了一个getter或setter时,这是另一个使用ivar语法的地方。 (感谢@ godel9)。 (记住:这是一个粗略的指导方针,还有其他的用例可能需要直接ivar访问)。

编辑:由于在评论一些批评:这是真的,点语法,也没有声明什么作为@property使用,例如一些使用array.count代替[array count](用于NSArray *array)。但鉴于OP询问了物业与Ivars的关系,这当然没有被问到。另请注意,对于给定的@property ... SomeClass *foo,伊娃不一定是_foo,但这将是最近ObjC编译器中自动生成的伊娃尔名称(可以将属性映射到任意伊瓦尔)。

+0

现在我明白了,非常感谢你! –

+0

另一个使用伊娃语法的地方是自定义getter和setter。 – godel9

+0

显然是真的,补充说。 –

3

有三种情况来考虑:

使用
  • someObject.something

  • 使用self->something

  • 使用otherObject->something

someObject.something点语法。就行为而言,它完全等同于[someObject something]。这是一个方法调用。请注意,something不必通过@property进行声明。也就是说,someArray.countsomeString.length在语法上都是有效的。

self->something正在直接访问伊娃。这是一个很少使用的语法;难得在几乎从未。相反,只需使用something =[something doSomething]直接访问伊娃。不需要->

otherObject->something直接围绕着otherObject的实例变量。糟糕的程序员。没有甜甜圈。不要这样做。它打破封装并导致非常脆弱,难以维护的代码。


@property声明的说明。如果您有:

@property (atomic, strong, readonly) SomeClass *foo; 

如果您自动让编译器@synthesize一切,它会创建一个名为_foo实例变量。

您应该在您的initdealloc方法中使用直接访问,但是 - 通常(尽管不总是) - 在其他地方使用setter/getter。即在你的init你会做_foo = [SomeClass someClassWithSomeMagicValue:42](假设ARC,所以没有retain需要)。在其他地方,你会做[[self foo] castMagic];

+0

最后两种情况是相同的情况。 – newacct

+0

@newacct不完全;第二种情况不会破坏封装,因为它正在访问正在执行方法的实例的实例变量。在第三种情况下,代码将访问某个* other *对象的iVar,破坏封装。 – bbum

+0

但这不是一个语言概念。这只是一个编程风格问题。 – newacct