2010-04-02 67 views
10

我可能會在這裏丟失一些明顯的東西,但是我在其中一個對象上實現了NSCopying。該對象具有不通過getter公開的私有實例變量,因爲它們不應該在對象之外使用。使用NSCopying複製私有實例變量的最佳做法

在我的copyWithZone:的實現中,我需要alloc/init新實例,還要設置其狀態以匹配當前實例。我顯然可以從copyWithZone:內部訪問當前的私有狀態,但我無法將其設置爲新對象,因爲沒有該狀態的訪問者。

有沒有一個標準的解決方法,同時仍然保持數據隱私完好?

謝謝。

回答

8

首先,你應該始終有干將,即使它們是私有的。你的對象應該只能訪問使用訪問器的自己的ivars(除了極少數情況)。這將爲您節省內存管理帶來的巨大痛苦。其次,Alex的使用 - >的建議是一種標準方法,儘管這違反了上面的getters規則。該規則有少數例外,並且副本是其中之一。在這裏使用私人設置器仍然是合理的(我以前只是這樣做),但是我發現,出於各種原因,使用 - >經常會使用更清潔的設備。

要非常小心地讓你的內存管理正確。如果您需要致電[super copyWithZone:],那麼您還應該瞭解NSCopyObject()的複雜性以及它對您的影響,即使您自己不使用它。我已經詳細討論了這個問題"NSCopyObject() considered harmful."

+0

感謝提及私有訪問器以及NSCopyObject的風險。 – 2010-04-02 15:40:40

+0

我不確定只讀訪問器如何幫助內存管理?如果你沒有用'assign'或'retain'來使用它,不管你是直接使用getter還是變量都沒有區別。 – Hemant 2011-01-20 03:22:05

+0

@Hemant,因爲調用者不需要小心該屬性目前(或將來)是否只讀。這不是調用者的業務,它可能會隨着時間而改變,然後您需要搜索不正確的代碼。通過堅持簡單的規則,錯誤變得明顯。當你說「哦,除非我碰巧知道它現在沒問題」,那麼你正在爲自己的維護問題而煩惱。 – 2011-01-20 19:44:05

5

您可以直接訪問副本的實例變量。您可以使用與結構一樣的指針解引用語法。因此,舉例來說,如果你的類是這樣的:

@interface MyCopyableClass : NSObject { 
    int anInstanceVariable; 
} 
@end 

你可以這樣做:

- (id)copyWithZone:(NSZone *)zone { 
    MyCopyableClass *theCopy = [[[self class] allocWithZone:zone] init]; 
    theCopy->anInstanceVariable = anInstanceVariable; 
    return theCopy; 
} 
1

一個選項是創建一個接受私有iVar值的自定義初始值設定項。所以你創建它像:

-(id) initWithPropertyOne:(SomeClass *) anObject andPropertyTwo:(SomeClass *) anotherObject; 

當你實例化副本,只需使用自定義初始值設定項。

相關問題