2013-05-29 21 views
0

澄清:這個問題不是關於mutable vs immutable,而是關於超級創建正確類的實例的調用。我沒有想過在基類中使用[[self class] alloc],這似乎解決了我的問題。如果沒有更好的出現:)mutableCopyWithZone令人困惑的要求?


The Apple spec says:

If a subclass inherits NSMutableCopying from its superclass and declares 
additional instance variables, the subclass has to override mutableCopyWithZone: 
to properly handle its own instance variables, invoking the superclass’s 
implementation first. 

這是非常令人困惑,我會接受在接下來的幾個小時是雁。考慮

@interface Base : NSObject<NSMutableCopying> 
@property (nonatomic, assign) NSInteger value ; 
@end 
@implementation Base 
... 
@end 


@interface Derived : Base<NSMutableCopying> 
@property (nonatomic, assign) NSInteger value2 ; 
@end 

@implementation Derived 

- (id) mutableCopyWithZone: (NSZone *) zone { 
    // Huh ??? 
    Derived * derived = [super mutableCopyWithZone: zone] ; 
    ... 
    // Huh ?????? 
    derived.value2 = self.value2 ; 
    return derived ; 
} 
... 
@end 

我只是不明白如果我遵循規範這個代碼可能是正確的。

當呼叫[super mutableCopyWithZone: zone]返回時,我期待基類只爲自己的ivars分配了足夠的空間。沒有辦法可以說明實例需要更多空間來存放自己的ivars。

這是什麼文檔意味着,真的嗎?我應該如何實現這一點?

+0

根據文檔,只有定義「不可變與可變」區別的類應採用NSMutableCopying協議。你有兩個'Derived'和'MutableDerived'類嗎? –

+0

我認爲,Derived是可變類,base是不可變類。 –

+1

如果Base是不可變類,那麼它不會採用NSMutableCopying協議。 –

回答

4

超級只改變調度方式(靜態而不是動態)。但它不會改變接收器,尤其是接收器。它不會倒塌。在-mutableCopyWithZone中:(super)self仍然指向派生類的實例對象。

麻煩是可能的,如果超級方法(或超級超級方法等)沒有實現以適當的方式創建對象:

copy = [[BaseClass alloc] init]; // Wrong, an instance of the base class is created 

copy = [[[self class] alloc] init]; // Correct, an instance of [self class] == DerivedClass is created 

使用第二種方法你派生的一個實例爲其ivars提供完整的內存。

結論:如果BaseClass正確地實現了它的-mutableCopyWithZone,就以這種方式實現它。否則,你沒有其他改變,然後創建自己的副本並初始化它。

在我的書裏,我總是寫道,沒有什麼理由在類中使用類名。使用[self class](在實例方法中)和self(在類方法中)99%是更好的方法。

+1

但是,如果調用'Derived'對象上的'mutableCopy'應該返回'MutableDerived'對象(比較我的註釋與問題),比如NSString和NSMutableString? - 我不確定這是如何與子類化工作。 –

+1

首先:我不認爲,他的問題指向了mutableCopy的特殊問題,但也要複製。(以及任何其他情況,其中一個實例必須由基類的一個方法創建(例如new,它在NSObject中實現,但創建了接收方cass的實例) 第二:在你的情況下,一個實例第三:如果-mutableCopy(沒有WithZone :)被髮送到ImmutableBase,則創建Derived,因爲消息被髮送到Derived並且[[self class] alloc](ImmutableBase)將創建Derived的一個實例,一切都很好 ImmutableBase「知道」它的子類 –

+1

不要誤解我的意思:我認爲你的答案對於NSCopying協議是正確的 - 我的意思是:發送mutableCopy到Derived實例應該返回一個MutableDerived對象。基類實現如何處理? - 我想知道NSMutableCopying和subclassing是如何協同工作的(一個「MutableDerived」類不能是子類「Derived」和「MutableBase」類 - 但這可能是一個不同的問題:-) –