2013-04-30 100 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