转自eseedo的博客   [微博]

NYTimes Objective-C 编程风格指南。来源:https://github.com/NYTimes/objective-c-style-guide
 
这篇指南总结了纽约时报iOS开发团队的编程风格。欢迎大家在github中提供建议和pull请求。
 
简介:
以下是形成本编程指南所涉及到的Apple官方文档。如果本文有未尽之处,可以参考以下链接:
 
目录
点表示法
空格
条件语句
三元运算子
方法
变量
命名
下划线
注释
初始化&内存释放
Literals字面量
CGRect 函数
常量
枚举类型
私有属性
图片名称
布尔变量
单例
Xcode项目
 
点表示法应“仅”用于获取和改变属性。括号表示法用于所有其它实例。
例如:
恰当用法:
view.backgroundColor = [UIColor orangeColor];
[UIApplication sharedApplication].delegate;
不当用法:
[view setBackgroundColor:[UIColor orangeColor]];
UIApplication.sharedApplication.delegate;
 
空格
(1)行缩进使用4个空格。禁止使用Tab键来缩进。请在Xcode偏好设置中进行设置。
(2)方法大括号和其它大括号(比如if/else/switch/while等等)应在语句的同一行开始,而在新的一行关闭。
例如:
if (user.isHappy) {
//Do something
}
else {
//Do something else
}
(3)为保证视觉上的整洁和代码组织,在方法之间应提供且仅提供一行空白。方法中的空白应用于区分功能,但空白行最好用于区分两个不同方法。
(4)@synthesize和@dynamic应在方法实现的新一行中声明。
 
条件语句
为避免错误,条件语句体必须使用大括号,即便语句体中的语句可以不必使用大括号(比如只有一行语句)。常见的错误包括在不使用大括号的情况下添加第二行语句,以为它属于if语句的一部分。此外,更可怕的事情是,如果条件语句中的代码行被注释,则本不术语条件语句的下一行代码将变成条件语句的一部分。此外,这种编码风格和所有其它条件语句均保持一致。
例如:
恰当用法:
if (!error) {
    return success;
}
 
不当用法:
if (!error)
    return success;
 
不当用法2:
if (!error) return success;
 
三元运算子
仅当使用该运算子可以让代码显得更清晰易懂时方可使用三元运算子。更多情况下应使用条件语句。使用类似if的条件语句对多种条件进行判断通常要更容易理解,或使用实例变量。
 
恰当用法:
result = a > b ? x : y;
 
不当用法:
result = a > b ? x = c > d ? c : d : y;
 
方法
在方法声明中,在(-/ )符号之后应加上一个空格。此外,在方法段之间应添加一个空格。
 
例如:
(void)setExampleText:(NSString *)text image:(UIImage *)image;
 
变量
变量的命名应尽可能具有自解释性。除了在for()循环语句中,应避免使用单个字母变量名称。
除非是常量,星号应紧贴变量名称表示指向变量的指针,比如:
 
正确用法:
NSString *text;
 
不当用法:
NSString* text;
 
NSString * text;
 
应尽可能使用属性定义替代单一的实例变量。避免在初始化方法,dealloc方法和自定义的setter和getter方法中直接读取实例变量参数(init,initWithCoder:,等等)。更多信息请参看here
 
例如:
恰当用法:
@interface NYTSection: NSObject
 
@property (nonatomic) NSString *headline;
 
@end
 
不当用法:
@interface NYTSection : NSObject {
    NSString *headline;
}
 
命名规范
苹果的命名规范应尽可能符合内存管理法则(NARC)memory management rules
 
在Objective-C中鼓励使用长的描述性的方法和变量名称。
 
例如:
恰当用法:UIButton *settingsButton;
 
不当用法:
UIButton *setBut;
 
对于类和常量名称,应尽量使用三大写字母前缀(比如NYT),但对Core Data的实体名称可不适用该法则。
 
常量名称应将其中的所有单词的首字母大写,同时加上相关类的名称作为前缀。
 
例如:
恰当用法:
static const NSTimeInterval NYTArticleViewControllerNavigationFadeAnimationDuration = 0.3;
不当用法:
static const NSTimeInterval fadetime = 1.7;
 
属性名称应使用camel-case(驼峰式)命名方法,且第一个单词的首字母应为小写。如果Xcode版本支持对变量的自动合成,则不必深究。否则与该属性对应的实例变量名称的第一个单词的首字母应为小写,且在前面加上下划线。
例如:
恰当用法:
@synthesize descriptiveVariableName = _descriptiveVariableName;
不当用法:
id varnm;
 
下划线
当使用属性变量时,应通过self.来获取和更改实例变量。这就意味着所有的属性将是独特的,因为它们的名称前会加上self.。本地变量名称中不应包含下划线。
 
注释
在需要注释的地方,应使用注释来解释某一块特定的代码的功能。所有的代码注释必须是最新的,要吗就删掉。
应尽量使用行注释,而避免使用块注释。之所以这样是因为代码自身需要是自文档化的,因此只需要零散添加一些行注释。当然,对于用于生成文档的注释,该原则并不适用。
 
初始化和内存释放
dealloc方法应放在方法实现文件的顶部,在@synthesize和@dynamic语句之后。init初始化方法应放在dealloc方法之后。
 
Literals字面量
在创建NSString,NSDictionary,NSArray和NSNumber等对象的immutable实例时,应使用字面量。需要注意的是,不应将nil传递给NSArray和NSDictionary字面量,否则会引起程序崩溃。
 
例如:
恰当用法:
NSArray *names = @[@"Brian", @"Matt", @"Chris", @"Alex", @"Steve", @"Paul"];
NSDictionary *productManagers = @{@"iPhone" : @"Kate", @"iPad" : @"Kamal", @"Mobile Web" : @"Bill"};
NSNumber *shouldUseLiterals = @YES;
NSNumber *buildingZIPCode = @10018;
 
不当用法:
NSArray *names = [NSArray arrayWithObjects:@"Brian", @"Matt", @"Chris", @"Alex", @"Steve", @"Paul", nil];
NSDictionary *productManagers = [NSDictionary dictionaryWithObjectsAndKeys: @"Kate", @"iPhone", @"Kamal", @"iPad", @"Bill", @"Mobile Web", nil];
NSNumber *shouldUseLiterals = [NSNumber numberWithBool:YES];
NSNumber *ZIPCode = [NSNumber numberWithInteger:10018];
 
CGRect函数
当需要获取一个CGRect矩形的x,y,width,height属性时,应使用CGGeometry函数,而非直接访问结构体成员。
 
例如:
恰当用法:
CGRect frame = self.view.frame;
 
CGFloat x = CGRectGetMinX(frame);
CGFloat y = CGRectGetMinY(frame);
CGFloat width = CGRectGetWidth(frame);
CGFloat height = CGRectGetHeight(frame);
 
不当用法:
CGRect frame = self.view.frame;
 
CGFloat x = frame.origin.x;
CGFloat y = frame.origin.y;
CGFloat width = frame.size.width;
CGFloat height = frame.size.height;
 
常量
相对字符串字面量或数字,我们更推荐适用常量。应使用static方式声明常量,而非使用#define的方式来定义宏。
 
例如:
恰当用法:
static NSString * const NYTAboutViewControllerCompanyName = @"The New York Times Company";  
 
static const CGFloat NYTImageThumbnailHeight = 50.0;
 
不当用法:
#define CompanyName @"The New York Times Company"
 
#define thumbnailHeight 2
 
枚举类型
在使用enum的时候,推荐适用最新的fixed underlying type(WWDC 2012 session 405- Modern Objective-C)规范,因为它具备更强的类型检查和代码完成功能。
例如:
typedef NS_ENUM(NSInteger, NYTAdRequestState) {
    NYTAdRequestStateInactive,
    NYTAdRequestStateLoading
};
 
私有属性
 
私有属性应在类实现文件的类扩展(匿名分类)中进行声明。应避免使用命名分类(比如NYTPrivate或private)。
例如:
@interface NYTAdvertisement ()
 
@property (nonatomic, strong) GADBannerView *googleAdView;
@property (nonatomic, strong) ADBannerView *iAdView;
@property (nonatomic, strong) UIWebView *adXWebView;
 
@end
 
图片名称
在命名图片名称的时候,应保持一致性,从而让开发团队和成员可以明白其含义。图片名称的第一个单词应描述其用途,并使用camel-case风格,然后是不带前缀的所属类名称或属性,最后是色彩、位置和状态。
 
例如:
RefreshBarButtonItem / RefreshBarButtonItem@2x and RefreshBarButtonItemSelected / RefreshBarButtonItemSelected@2x
ArticleNavigationBarWhite / ArticleNavigationBarWhite@2x and ArticleNavigationBarBlackSelected / ArticleNavigationBarBlackSelected@2x.
 
布尔变量
因为nil将被解析为NO,因此没有必要在条件语句中进行比较。永远不要将任何东西和YES进行直接比较,因为YES被定义为1,而一个BOOL变量可以有8个字节。
例如:
恰当用法:
if (!someObject) {
}
 
不当用法:
if (someObject == nil) {
}
 
以下是BOOL变量的使用:
恰当用法:
if (isAwesome)
if (![someObject boolValue])
 
不当用法:
if ([someObject boolValue] == NO)
if (isAwesome == YES) // Never do this.
 
如果一个BOOL属性使用形容词来表达,属性将忽略’is’前缀,但会强调惯用名称。
例如:
@property (assign, getter=isEditable) BOOL editable;
 
单例
在创建单例对象的共享实例时,应使用线程安全模式。
例如:
(instancetype)sharedInstance {
   static id sharedInstance = nil;
 
   static dispatch_once_t onceToken;
   dispatch_once(&onceToken, ^{
      sharedInstance = [[self alloc] init];
   });
 
   return sharedInstance;
}
 
Xcode项目
为避免文件混乱,实际的物理文件应和Xcode项目保持一直。在Xcode中所创建的任何group都应有文件系统中相对应的文件夹。不应仅根据文件类型来进行分组,还需要考虑到其作用。
 
在Xcode的target的Build Setting中,中尽量开启”Treat Warnings as Errors“,同时尽量开启其他的警告additional warnings。如果需要忽略某个特定的警告,可以使用Clang's pragma feature
 
如果以上编码风格不合你的口味,还可以参考以下几个风格指南:

NYTimes Objective-C 编程风格指南的更多相关文章

  1. Google Java编程风格指南

    出处:http://hawstein.com/posts/google-java-style.html 声明:本文采用以下协议进行授权: 自由转载-非商用-非衍生-保持署名|Creative Comm ...

  2. Google Java编程风格指南中文版

    作者:Hawstein出处:http://hawstein.com/posts/google-java-style.html声明:本文采用以下协议进行授权: 自由转载-非商用-非衍生-保持署名|Cre ...

  3. Java学习笔记(四)——google java编程风格指南(上)

    [前面的话] 年后开始正式上班,计划着想做很多事情,但是总会有这样那样的打扰,不知道是自己要求太高还是自我的奋斗意识不够?接下来好好加油.好好学学技术,好好学习英语,好好学习做点自己喜欢的事情,趁着自 ...

  4. Java学习笔记(五)——google java编程风格指南(中)

    [前面的话] 年后开始正式上班,计划着想做很多事情,但是总会有这样那样的打扰,不知道是自己要求太高还是自我的奋斗意识不够?接下来好好加油.好好学学技术,好好学习英语,好好学习做点自己喜欢的事情,趁着自 ...

  5. Java学习笔记(六)——google java编程风格指南(下)

    [前面的话] 年后开始正式上班,计划着想做很多事情,但是总会有这样那样的打扰,不知道是自己要求太高还是自我的奋斗意识不够?接下来好好加油.好好学学技术,好好学习英语,好好学习做点自己喜欢的事情,趁着自 ...

  6. MATLAB 编程风格指南及注意事项

    MATLAB编程风格指南Richard Johnson 著Genial 译MATLAB 编程风格指南Richard JohnsonVersion 1.5,Oct. 2002版权: Datatool 所 ...

  7. Swift 编程风格指南(raywenderlich.com 版本号)

    官方 raywenderlich.com Swift 编程风格指南 本文版权归 raywenderlich.com .The Official raywenderlich.com Swift Styl ...

  8. Google的Java编程风格指南(Java编码规范)

    这份文档是Google Java编程风格规范的完整定义.当且仅当一个Java源文件符合此文档中的规则, 我们才认为它符合Google的Java编程风格. 与其它的编程风格指南一样,这里所讨论的不仅仅是 ...

  9. Google C++编程风格指南

    作者:Hawstein 出处:http://hawstein.com/posts/google-cpp-style-guide.html 前言 越来越发现一致的编程风格的重要性,于是把Google的C ...

随机推荐

  1. [Z] 关于Python Tornado的一些资料

    一个简单的样例: http://osedu.net/article/python/2014-03-18/501.html ioloop的官方doc: http://www.tornadoweb.org ...

  2. MySQL group_concat_max_len

    MySQL提供的group_concat函数可以拼接某个字段值成字符串,如 select group_concat(user_name) from sys_user,默认的分隔符是 逗号,即" ...

  3. MPEG-2码流结构分析

    MPEG2视频编码定义在 ISO/IEC13818-2中,MPEG2 video sequence如下图所示 我们可以借助Elecard Stream Analyer工具来分析MPEG2视频码流 MP ...

  4. C++提高编译与链接速度的资料

    1,https://blog.csdn.net/lihao21/article/details/47610309 2,https://www.zhihu.com/question/37330979 3 ...

  5. jena读取和解析本体文件

    使用jena开发本体应用程序时,首先需要对我们利用本体构建工具,如protege等,构建的本体文件,如owl.rdf等读取并解析得到本体模型.下面给出相应的代码,不对的地方请指正. (基于jena 2 ...

  6. 重构--去除丑陋的switch语句

    最近几天,在进行重构的时候,遇到了一个极其丑陋的代码(自己写的 /捂脸  当时时间紧,于是....),今天去重构的时候无论如何也想不出方法,去除这个丑陋的switch语句 ,于是写篇博客,让自己记住这 ...

  7. DEV上肤

    1,在Main中加入此语句DevExpress.UserSkins.BonusSkins.Register();SkinManager.EnableFormSkins();DevExpress.Loo ...

  8. Texture Combiner

    [Texture Combiner] After the basic vertex lighting has been calculated, textures are applied. In Sha ...

  9. Kubuntu上截屏的小技巧

    Kubuntu上自带了截屏软件ksnapshot,只需要按Print Screen就会自动调起,实际上挺方便的:但是,Print Screen的默认行为是截下整个屏幕,这往往不是我们需要的. 实际上, ...

  10. 配置jdk和tomcat的环境变量

    一.1,新建变量名:JAVA_HOME,变量值:d:\Program Files\Java\jdk1.7.0 2,打开PATH,添加变量值:%JAVA_HOME%\bin;%JAVA_HOME%\jr ...