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
若是以上编码风格不合你的口味,还能够参考如下几个风格指南: