2012-11-23 70 views
1

好的,我知道這個主題在SO之前多次提到過,但在查看了幾個這樣的問題之後,沒有人談論過我關於覆蓋子類中的基類getter/setter。房地產類型與訪問者類型不匹配(當子類化時)

我的基類是:

#import <Foundation/Foundation.h> 
@interface BaseClass : NSObject 
@property (nonatomic, assign) int value; 
@end 

@implementation BaseClass 
@synthesize value; 
@end 

從我想要的子類作爲一個墊片,並在我的子類,從一個int「值」映射到一個枚舉:

#import <UIKit/UIKit.h> 
#import "BaseClass.h" 

typedef enum { 
    zero = 0, 
    one, 
    two, 
    three, 
    four 
} NumberEnum; 

@interface ChildClass : BaseClass 
-(void)setValue:(NumberEnum)newValue; 
-(NumberEnum)value; 
@end 

@implementation ChildClass 

-(void)setValue:(NumberEnum)newValue 
{ 
    [super setValue:(int)newValue]; 
    NSLog(@"Child Setter"); 
} 

-(NumberEnum)value 
{ 
    NSLog(@"Child Getter"); 
    return (NumberEnum)[super value]; 
} 

@end 

我使用測試此代碼:

ChildClass* fred = [[ChildClass alloc] init]; 
NumberEnum barney; 
fred.value = one; 
barney = fred.value; 
barney = [fred value]; 

的XCode(4.5.2)生成警告

屬性「價值」不匹配訪問「價值」

的類型在此行中類型:

barney = fred.value; 

當運行的代碼,我看到日誌適用於兒童安裝人員和Getter的消息。那麼,我應該怎樣做才能消除這個警告,爲什麼我首先得到它?

回答

0

出錯行:

barney = fred.value; 

告訴您要使用的屬性,則編譯value 。由於你的孩子班級沒有定義它,它會上升到基類。它發現了value與一個不同的類型導致警告。

一個解決辦法是寫你的屬性爲:

@property (nonatomic, assign) int value; 

和枚舉爲:

enum { 
    zero = 0, 
    one, 
    two, 
    three, 
    four 
}; 
typedef int NumberEnum; 

這樣合成的特性的方法和自己的實現與相同的數據類型的工作。您可以使用符號值並且沒有警告。

我建議使用NSUInteger,因爲它是64位友好的。

當然,如果您只是在基類中將該屬性定義爲NumberEnum會好得多。

+0

無論是fred.value和[弗雷德值]呼叫通過吸氣在子類中定義。我的理解是,fred.value語法確實是一個隱式[fred值]的語法糖,因此我希望在兩行或兩行中都有警告。不過,我確實同意你的解決方案可行! (或者當然,首先繼承的全部原因是我有多個子類,它們有一些我正在推入基類的通用代碼) –

1

你的@propertyint和編譯器可能搞亂你的方法。嘗試@property類型設置爲NumberEnum,它應該工作(你需要將枚舉定義移動到您的.h)

+0

我不能將枚舉移動到基類,因爲基類被用作多個子類的低音類。 –

+0

@PeterM然後,你不能改變子類中的屬性或其訪問器的類型。 –

+0

那麼也許你有一些設計問題,如果你的子類處理相同屬性的不同類型,即使它將int更改爲枚舉器。也許在你的'ChildClass'中創建一個新的屬性,然後在那裏覆蓋'value' getter/setter方法。 – Ismael