2008-10-10 23 views
41

responsethis question他指出「一般來說,你應該而不是在dealloc(或init)中使用訪問器方法。」爲什麼mmalc會這樣說?爲什麼我不應該在init/dealloc中使用Objective C 2.0訪問器?

我能想到的唯一真正原因是性能和避免@dynamic setter的未知副作用。

討論?

+0

它的OP沒有結束「討論?」這不會被關閉。這是一個非常合理和有用的問題 - 非常有建設性。 – Phil 2014-09-12 22:56:33

回答

19

這是關於使用慣用一致的代碼。如果適當地對所有代碼進行構造,則有一組規則可以確保在init/dealloc中使用訪問器是安全的。

最大的問題是(如mmalc所說)設置屬性默認狀態的代碼不應該通過訪問器,因爲它會導致各種討厭的問題。問題在於,init沒有必要設置屬性的默認狀態。由於一些原因,我一直移動到該自助初始化存取,如下面的簡單的例子:

- (NSMutableDictionary *) myMutableDict { 
    if (!myMutableDict) { 
     myMutableDict = [[NSMutableDictionary alloc] init]; 
    } 

    return myMutableDict; 
} 

屬性初始化的這種風格的一個推遲了很多初始化代碼實際上可能沒有必要。在上述情況下,init不負責啓動屬性狀態,並且在init方法中使用訪問器是完全安全的(甚至是必需的)。無可否認,這會對代碼施加額外的限制,例如,對於超類中屬性的自定義訪問器的子類必須調用超類訪問器,但這些限制並不符合可可中常見的各種其他限制。

29

這基本上是一個指導方針,以儘量減少錯誤的可能性。

在這種情況下,您的setter/getter可能會無意中對對象的狀態進行直接或間接假設。當物體處於被設置或被破壞的狀態時,這些假設可能是一個問題。

例如,在下面的代碼中,觀察者不知道'示例'正在被銷燬,並且可能假設已經被釋放的其他屬性是有效的。

(你可能會認爲你的對象應該先刪除所有的觀察者,然後再撕掉,這是很好的做法,另一個指導方針可以防止無意的問題)。

@implementation Example 

-(void) setFoo:(Foo*)foo 
{ 
    _foo = foo; 
    [_observer onPropertyChange:self object:foo]; 
} 

-(void) dealloc 
{ 
    ... 
    self.foo = nil; 
} 

@end 
+2

我明白你在說什麼,但我並沒有真正購買它。 唯一真正的副作用是KVO在對象處於dealloc中時被激發。這真的很糟糕嗎?我一直這樣做了一會兒(在objc2之前使用[self setFoo:NULL]風格)並且還沒有看到一個問題。 – schwa 2008-10-10 21:37:50

+2

我很喜歡一些可以說明問題的示例代碼 - 如果有的話。有人知道嗎? :-) – schwa 2008-10-10 21:39:56

+0

就像我說過的,這只是一個指導方針,可以最大限度地減少潛在的問題。與人們推薦的方式相同,將釋放的指針設置爲NULL。 – 2008-10-10 22:58:04

15

你回答了自己的問題:

  1. 性能可能是完全足夠的理由本身(特別是如果你的訪問器是原子)。
  2. 您應該避免訪問者可能產生的任何副作用。

如果你的課程可能被分類,後者尤其成爲一個問題。

目前還不清楚,但是,爲什麼這是專門在Objective-C的2個存取解決?無論您使用聲明的屬性還是自己寫入訪問器,都適用相同的原則。

2

這可能是二傳手有應該運行或者可能實現使用伊娃與名來自的getter/setter也許兩高德需要不同的釋放和/或有其值設置爲無邏輯。唯一可靠的方法是打電話給二傳手。在init或dealloc中被調用時,setter的責任是這樣寫的,以避免不希望的副作用發生。

從「可可設計模式」,Buck,Yacktman,第115頁:「...在現代Objective-C運行時使用合成實例變量或使用訪問器時沒有實際的替代方法或...」

0

事實上,對於一個經常進來的類(比如一個詳細視圖控制器),你想在init中使用訪問器;否則,你可能最終會釋放在viewDidUnload您稍後嘗試訪問的值(它們表明,在CS193P ...)

0

您可以通過分配/解除分配時沒有要求二傳手創建相同的問題。

我不認爲你可以通過直接在init/dealloc中使用retain/release來實現任何功能。你只需改變一組可能的錯誤。

每次你必須考慮財產分配/取消分配的順序。

相關問題