2013-10-26 54 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