在开始时宣布,或在你去的时候宣布?

fuz*_*oat 3 cocoa-touch objective-c

我会说这几乎是一个样式/可读性的东西,虽然我确实看到几乎所有的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];

}
Run Code Online (Sandbox Code Playgroud)

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];

}
Run Code Online (Sandbox Code Playgroud)

加里

Rob*_*ier 5

METHOD_002肯定.虽然有些人可能会提出METHOD_001的理由,但它主要是出于技术和历史原因.较旧的C编译器需要在任何可执行代码之前定义的所有堆栈变量(局部变量).这是ANSI标准的一部分.它不再是,而且应该被归为历史.

METHOD_002有几个优点:

  • 它鼓励阻止范围界定.通过在块内部定义变量(例如for()循环),该变量不能在其有意义的范围之外被意外使用.ANSI通过在块的顶部定义变量来允许块作用域,但是我发现一旦人们习惯于在函数的顶部进行声明,它很少在实践中以这种方式完成.

  • 它捕获了其他意外重复使用.例如,您在函数顶部定义变量"result"并将其指定为nil.您的代码假定在某个循环开始时它为NULL.然后在函数顶部插入更多代码,并通过习惯重用变量"result".您可能刚刚为后面的代码创建了意外的副作用.如果您使用METHOD_002,那么您将使前一个结果块本地化,或者当您在同一范围内重新声明具有相同名称的另一个变量时,您将收到编译器错误.

  • 它使得Extract重构更加容易,因为变量声明通常会接近使用它们的代码.提取也不太可能产生意想不到的副作用,因为变量不太可能在代码的不同区域中重用.

  • 它减少了"残酷"的可能性.当删除使用它们的代码时,函数顶部的变量很少被删除.编译器可以优化它,但它仍然是代码残留.

  • 它通过较少的变量重用来鼓励更有意义的名称.在实践中,我发现当人们在函数顶部声明变量时,他们更可能只是通过函数重用一些名为"tmpValue"的变量用于几种不同的用途.没有理由这是真的,但我发现变量声明来自使用它的代码越远,人们就越不可能不厌其烦地宣布一个新变量.有一些事情比防止好的命名更能防止错误.

我用METHOD_002找到了一个缺点:

  • 找到变量的类型更难.这对于IDE来说不太重要,因为您通常可以轻松跳转到其声明.我认为变量的名称通常应该使其类型明显.但是,有时候很难找到这种类型.作为必然结果,有时可能难以确定变量的范围.