2013-04-30 97 views
1

我正在編寫一個訪問API的客戶端。該API吐出這樣的:Objective-C:屬性類型轉換的自定義設置警告

Id: 33, 
UserUrl: "https://example.com/username/profile", 
Title: "I wanna give 'em the holy boot!", 
IsOnline: "no" 

我消耗了JSON作爲NSDictionary中使用setValuesForKeysWithDictionary其轉換爲我的用戶對象:。我User.m定製制定者採取傳入UserUrl串並彎曲成一個NSURL像這樣:

- (void)setUserUrl:(NSString *)stringInput { 
    _UserUrl = [NSURL URLWithString:stringInput]; 
} 

這工作得很好。當我嘗試用布爾值將是相同的,我得到一個警告:

在執行相互衝突的參數類型「setIsSecret:」:「BOOL」(又名「符號字符」)與「的NSString * __強」

- (void)setIsOnline:(NSString *)stringInput { 
     if ([stringInput isEqualToString:@"yes"]) 
      _IsOnline = YES; 
     else 
      _IsOnline = NO; 
    } 

User.h

@interface Achievement : NSObject 

    @property (strong, nonatomic) NSNumber *Id; 
    @property (strong, nonatomic) NSURL *UserUrl; 
    @property (strong, nonatomic) NSString *Title; 
    @property (nonatomic) BOOL IsOnline; 

@end 

我的代碼編譯並運行正常,我只是想知道爲什麼會警告我的BOOL財產,但不NSString的財產。這是一個API包裝,所以我寧願不要抑制警告。提前致謝。

UPDATE rmaddy有正確的答案。對於將來要做同樣事情的任何人,請創建一個自定義初始值設定項來執行所有類型的轉換。

回答

1

您聲明IsOnline屬性的類型爲BOOL,但您的setIsOnline:方法需要NSString *參數。它需要是一個BOOL參數。

記住,IsOnline屬性導致合成方法:

- (BOOL)IsOnline; 

- (void)setIsOnline:(BOOL)value; 

與其它語言不同,Objective-C的不支持方法重載。參數的數據類型不是方法名稱的一部分。您的:

- (void)setIsOnline:(NSString *)value 

方法與期望值衝突。

您的setUserUrl:方法也會出現相同的錯誤,因爲屬性類型爲NSURL *,但您的方法需要NSString *。我不確定你爲什麼沒有這個問題。

如果您需要一個單獨的方法來設置給定不同類型的屬性,那麼您應該有一個方法名稱與標準屬性setter方法名稱不同。

備註 - 標準做法是變量,屬性和方法名以小寫字母開頭,而不是大寫字母。只有類應以大寫字母開頭。

+0

我想我可以重載setters(嗯,我想我技術上*可以*因爲代碼運行得很好)。我現在很好奇,爲什麼NSString/NSURL屬性不給我相同的警告。我發現警告只發生在試圖從對象轉換爲基元時,而不是在對象之間轉換。無論如何,這是有幫助的。並感謝風格筆記。 – Eric 2013-04-30 22:30:58

+0

我想我可以猜測你的NSString/NSURL屬性「排序」是有效的,因爲它們都是對象。但是我敢打賭,如果你真的爲該屬性指定了一個'NSURL'值,你的setter將被調用,並且你的代碼將會崩潰,因爲你最終會傳遞一個'NSURL'對象給'URLWithString:'方法。嘗試一下。 – rmaddy 2013-04-30 22:39:01

+0

是的,與'NSInvalidArgumentException'崩潰,原因:' - [NSURL長度]:無法識別的選擇器發送到實例。我通過添加一個客戶初始化程序使這個更加清潔。 – Eric 2013-04-30 23:17:12