我正在尝试了解UIPageControl的工作方式。所以我从Apple下载了这个示例代码 UIPageControlSampleCode 它运行正常,但在以下代码的if语句中有一个警告(使用赋值的结果作为没有括号的条件):
- (id)initWithPageNumber:(int)page
{
if (self = [super initWithNibName:@"MainView" bundle:nil])
{
pageNumber = page;
}
return self;
}
现在我的问题是:为什么开发人员会这样做?在if语句条件中进行赋值?这是一个错误吗?
答案 0 :(得分:1)
赋值运算符(=)除执行赋值外,还返回赋值。这样你可以做像
这样的事情a = b = 1;
编译器与编写
相同a = (b = 1);
这意味着在做
时self = <some init function>;
您可以通过将赋值放在if语句中来检查init是否成功。如果成功则返回一个有效指针,该指针不为零,这意味着if语句的条件为真。如果init失败,则返回nil,实际上为零,因此继续进行剩余的初始化是没有意义的。
警告的原因是很容易在if语句而不是(==)中意外使用(=):
if ( a = 1 ) // Should be a == 1
{
// Do important stuff
}
所以编译器试图保护你免受这个错误。
出于这个原因,我更喜欢在你的例子中明确表达条件:
if ((self = [super initWithNibName:@"MainView" bundle:nil]) != nil)
答案 1 :(得分:0)
此警告是因为Apple已创建示例代码,因此编译器版本和默认编译器选项已更改。
特别是,这个警告 - 告诉你你可能意味着“==”而不是“=”(因为语句处于“if”条件而你通常测试的是相等而不是分配) - 是相当的逻辑;但是默认情况下,在早期版本的编译器和Xcode 中没有激活警告,这解释了为什么这些代码可能仍然存在于旧的示例代码中(没有人是完美的,甚至Apple开发人员; ))
正确的正常使用/惯例是:
if (nil != (self = [super initWithNibName:@"MainView" bundle:nil]))
if ((self = [super initWithNibName:@"MainView" bundle:nil]))
也会起作用并删除警告。我建议采用第一种解决方案。
如果你明确地测试了,在赋值之后,赋值的结果(因此self
中的值)不是nil,那么当你读取代码时(即使它不是你的代码),你就确定了什么打算。
即使代码以这种方式保存代码(并保持警告),代码仍然有效,此警告可确保您在代码中没有错误输入'='而不是'==',因为这样可能是一个常见的错误(对于新手而且对于可能输入太快的有经验的程序员来说;))所以我认为它现在被激活是一件好事,并且为了清楚地与nil进行比较是一个好的做法清晰度