我会说这几乎是一种风格/可读性的东西,虽然我确实看到几乎所有的Objective-c / cocoa按照“METHOD_002”进行格式化。我只是好奇如果“METHOD_001”被认为是坏的风格,将所有声明放在方法的顶部是有好处的,但是如果你没有声明使用它们的对象,那么在可读性方面又有缺点吗?
METHOD_001
-(IBAction)dateButtonPressed {
NSDate *dateSelected;
NSString *dateString;
NSArray *dateItems;
NSString *alertMessage;
UIAlertView *alert;
dateSelected = [datePicker date];
dateString = [[NSString alloc] initWithFormat:@"%@", dateSelected];
dateItems = [dateString componentsSeparatedByString:@" "];
alertMessage = [[NSString alloc] initWithFormat:@"Date: %@ Time: %@", [dateItems objectAtIndex:0], [dateItems objectAtIndex:1]];
alert = [[UIAlertView alloc] initWithTitle:@"You Selected"
message:alertMessage
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
[alertMessage release];
[dateString release];
}
METHOD_002
-(IBAction)dateButtonPressed {
NSDate *dateSelected = [datePicker date];
NSString *dateString = [[NSString alloc] initWithFormat:@"%@", dateSelected];
NSArray *dateItems = [dateString componentsSeparatedByString:@" "];
NSString *alertMessage = [[NSString alloc] initWithFormat:@"Date: %@ Time: %@", [dateItems objectAtIndex:0], [dateItems objectAtIndex:1]];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"You Selected"
message:alertMessage
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
[alertMessage release];
[dateString release];
}
加里
答案 0 :(得分:5)
METHOD_002肯定。虽然有些人可能会提出METHOD_001的理由,但它主要是出于技术和历史原因。较旧的C编译器需要在任何可执行代码之前定义的所有堆栈变量(局部变量)。这是ANSI标准的一部分。它不再是,而且应该被归为历史。
METHOD_002有几个优点:
它鼓励块区域划分。通过在块内部定义变量(例如for()循环),该变量不能在其有意义的范围之外被意外使用。 ANSI通过在块的顶部定义变量来允许块作用域,但是我发现一旦人们习惯在函数的顶部进行声明,它很少以这种方式完成。
它捕捉到其他意外重复使用。例如,您在函数顶部定义变量“result”并将其指定为nil。您的代码假定在某个循环开始时它为NULL。然后在函数顶部插入更多代码,并通过习惯重用变量“result”。您可能刚刚为后面的代码创建了意外的副作用。如果您使用METHOD_002,那么您将使前一个结果块本地化,或者当您在同一范围内重新声明另一个具有相同名称的变量时,您将收到编译器错误。
它使得Extract重构更加容易,因为变量声明通常会接近使用它们的代码。提取也不太可能产生意想不到的副作用,因为变量不太可能在代码的不同区域重复使用。
它减少了“残酷”的可能性。当删除使用它们的代码时,函数顶部的变量很少被删除。编译器可以优化它,但它仍然是代码残留。
它通过较少的变量重用来鼓励更有意义的名称。在实践中,我发现当人们在函数顶部声明变量时,他们更可能只是通过函数重用一些名为“tmpValue”的变量用于几种不同的用途。没有理由这是真的,但我发现变量声明来自使用它的代码越远,人们就越不可能不厌其烦地宣布一个新变量。除了良好的命名之外,没有什么比防止错误更好的了。
我发现METHOD_002有一个缺点:
答案 1 :(得分:1)
我倾向于赞成“METHOD_002”。它似乎更简洁,更容易阅读,虽然这可能只是因为我已经习惯了。
我认为“METHOD_001”的优势在于,如果您决定将局部变量提升为实例变量,则只需删除方法顶部的本地声明,而不是寻找其声明。我只能预见这会成为非常大的方法的问题。
答案 2 :(得分:1)
绝对是METHOD_002。在我编写长,长,长的ASP代码块的那天,我被告知METHOD_001,然后将所有变量列在顶部似乎是有道理的,就像警告一样(在这个旅程中我们将遇到以下内容...... )。然而,在实践中,人们会盯着一种名为strFwdBck的东西,并想知道那天特定的咖啡是什么。我们当时没有“未使用的变量”警告,至少不是我所知道的。
现在我只是声明我真正需要的东西并立即使用它。即便如此,我经常回去收紧事情。
-(IBAction)dateButtonPressed {
NSString *dateString = [[NSString alloc] initWithFormat:@"%@", [datePicker date]];
NSArray *dateItems = [dateString componentsSeparatedByString:@" "];
NSString *alertMessage = [[NSString alloc] initWithFormat:@"Date: %@ Time: %@", [dateItems objectAtIndex:0], [dateItems objectAtIndex:1]];
[dateString release];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"You Selected"
message:alertMessage
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
[alertMessage release];
}
答案 3 :(得分:1)
我通常将两者混合在一起。如果变量只分配一次,那么我使用method_002。这使声明保持在使用变量的位置。但是,如果变量被多次分配,我使用method_001,因为那时我不必寻找代码来查找定义。
后一种情况的例子:
使用method_002:
-(void) someMethod{
//...some code
SomeClass *myVar=[assign someValue];
//...some more code
if (someTest) {
myVar=someValue;
}else{
myVar=someOtherValue;
}
}
如果您回到代码并查看myVar=someOtherValue;
,您将不得不重新编写代码来查找定义。相反,如果你使用method_001,你会得到:
-(void) someMethod{
SomeClass *myVar;
//...some code
myVar=[assign someValue];
//...some more code
if (someTest) {
myVar=someValue;
}else{
myVar=someOtherValue;
}
}
您只需跳到顶部即可查看定义。
如果您始终如一地使用此样式,您将自动知道在函数/方法开头定义的任何变量将具有多个赋值,而在正文中定义的任何变量都不会。
这真的有助于理解,特别是如果你花了很多时间回到你已经完全忘记的旧代码。
答案 4 :(得分:0)
对于这两种风格都有很好的论据,但我建议你去做你曾经做过的事情,或者更重要的是,无论你的客户和/或雇主使用什么格式。
无论您为个人项目选择什么,只要始终如一地 - 当您试图避免引入恼人/愚蠢的语法错误时,一致性会有很大帮助。 (在没有外部指导的情况下,我使用google's style guide)
答案 5 :(得分:0)
我认为你的方法2实际上是方法1和我称之为方法3之间的1/2方式
方法3是在代码中的任何地方声明变量的地方,就在它们第一次使用之前。如果那是在函数的末尾那么就是它。
示例中方法1和2之间的区别似乎主要是初始化问题。我认为在声明变量时输入变量是一个好主意,并且具有可读性。但是,我也倾向于认为在顶部声明变量使调试更容易。如果您没有从上到下阅读函数,那么弄清楚变量的声明位置以及变量的类型可能会很棘手。
当你有很长的功能(你不应该做什么,但它最终会发生),这大部分成为一个问题,所以20行进入你声明变量的函数,然后再使用它50行后再过20行。如果你只是去功能的开头,那就找出它的类型会更容易看看......
然而,正如你所说,这是一个风格问题,所以最终成为一个意见问题......