据此本人在网上查找到,觉得可以当作这些项目标Objective-C的编码标准

Ray Wenderlich 的 Objective-C编码规范,raywenderlich

鉴于自家正在预备模仿饿了么这一个app,到时只怕有点iOS开发者加入进去。那时如若每一个人的Objective-C编码风格都不等同,那样不易于保持代码一致性难以Code
Review
。所以本身在网上寻找到 The official raywenderlich.com Objective-C
style
guide那篇有关Objective-C编码风格的文章,觉得可以作为这些类型的Objective-C的编码标准,所以就翻译那篇小说。

raywenderlich.com Objective-C编码规范

那篇编码风格指南总结了raywenderlich.com的编码规范,只怕某些删减或涂改。

在多少人支付同1个app时,假若各种人的Objective-C编码风格都差距,这样不易于保持代码一致性难以Code
Review
。所以自身在网上搜索到 The official raywenderlich.com Objective-C
style
guide
那篇有关Objective-C编码风格的小说,觉得可以作为这么些类型的Objective-C的编码标准,所以就翻译那篇小说。

介绍

作者们制订Objective-C编码规范的案由是我们可以在大家的书,教程和初学者工具包的代码保持优雅和同样。固然大家有诸多见仁见智的撰稿人来成功不一样的书本。

此地编码规范有只怕与您看看的任何Objective-C编码规范差异,因为它重假诺为着打印和web的易读性。

raywenderlich.com Objective-C编码规范

那篇编码风格指南回顾了raywenderlich.com的编码规范,只怕有点删减或改动。

至于小编

那编码规范的制造是由许多来源raywenderlich.com团队成员在NicholasWaynik的起头下共同已毕的。团队成员有:Soheil Moayedi Azarpour, RicardoRendon Cepeda, 托尼 Dahbura, Colin Eberhardt, 马特 Galloway, GregHeo, Matthijs Hollemans, Christopher LaPollo, Saul Mora, AndyPereira, Mic Pringle, Pietro Rea, Cesare Rocchi, 马林 Todorov, NicholasWaynik和Ray Wenderlich

笔者们也拾分感激New York Times 和罗布ots &
Pencils’Objective-C编码规范的撰稿人。那多少个编码规范为本指南的创立提供很好的源点。

介绍

我们制订Objective-C编码规范的原由是大家可以在大家的书,教程和初学者工具包的代码保持优雅和均等。即便大家有诸多不一的撰稿人来成功不一样的书本。

那边编码规范有只怕与你看来的别样Objective-C编码规范差距,因为它紧假诺为着打印和web的易读性。

背景

此间某些关于编码风格Apple官方文档,若是略微东西一向不提及,可以在以下文档来寻找越来越多细节:

  • The Objective-C Programming Language
  • Cocoa Fundamentals Guide
  • Coding Guidelines for Cocoa
  • iOS App Programming Guide

有关我

那编码规范的创制是由许多源于raywenderlich.com团队成员在NicholasWaynik的领路下共同完毕的。团队成员有:Soheil Moayedi
Azarpour
,
Ricardo Rendon
Cepeda
,
Tony Dahbura,
Colin
Eberhardt
,
Matt
Galloway
,
Greg Heo,
Matthijs
Hollemans
,
Christopher
LaPollo
,
Saul Mora,
Andy Pereira,
Mic Pringle,
Pietro Rea,
Cesare Rocchi,
Marin Todorov,
Nicholas
Waynik
Ray
Wenderlich

咱俩也格外多谢New York
Times

Robots &
Pencils’
Objective-C编码规范的小编。那八个编码规范为本指南的创立提供很好的源点。

语言

应当利用US马耳他语.

应该:

1 UIColor *myColor = [UIColor whiteColor];

不应该:

1 UIColor *myColour = [UIColor whiteColor];

背景

此地有些关于编码风格Apple官方文档,假设稍微东西向来不提及,可以在偏下文档来探寻越来越多细节:

代码协会

在函数分组和protocol/delegate完毕中动用#pragma mark -来分类方法,要依据以下一般结构:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 #pragma mark - Lifecycle   - (instancetype)init {} - (void)dealloc {} - (void)viewDidLoad {} - (void)viewWillAppear:(BOOL)animated {} - (void)didReceiveMemoryWarning {}   #pragma mark - Custom Accessors   - (void)setCustomProperty:(id)value {} - (id)customProperty {}   #pragma mark - IBActions   - (IBAction)submitData:(id)sender {}   #pragma mark - Public   - (void)publicMethod {}   #pragma mark - Private   - (void)privateMethod {}   #pragma mark - Protocol conformance #pragma mark - UITextFieldDelegate #pragma mark - UITableViewDataSource #pragma mark - UITableViewDelegate   #pragma mark - NSCopying   - (id)copyWithZone:(NSZone *)zone {}   #pragma mark - NSObject   - (NSString *)description {}

目录

<b id=”language”></b>

空格

  • 缩进使用4个空格,确保在Xcode偏好设置来安装。(raywenderlich.com使用2个空格)
  • 主意大括号和其余大括号(if/else/switch/while 等.)总是在一如既往行语句打开但在新行中关闭。

应该:

1 2 3 4 5 if (user.isHappy) {     //Do something } else {     //Do something else }

不应该:

1 2 3 4 5 6 7 if (user.isHappy) {   //Do something } else {   //Do something else }
  • 在艺术之间应当有且只有一行,这样便于在视觉上更清楚和更便于社团。在点子内的空域应该分别成效,但普通都抽离出来改成三个新章程。
  • 优先使用auto-synthesis。但一旦有必要,@synthesize 和 @dynamic应该在完毕中各种都宣称新的一条龙。
  • 应该防止以冒号对齐的格局来调用方法。因为有时候方法签名或者有贰个以上的冒号和冒号对齐会使代码尤其易读。请不要如此那般做,纵然冒号对齐的法门包蕴代码块,因为Xcode的对齐方式令它难以辨认。

应该:

1 2 3 4 5 6 // blocks are easily readable [UIView animateWithDuration:1.0 animations:^{   // something } completion:^(BOOL finished) {   // something }];

不应该:

1 2 3 4 5 6 7 8 // colon-aligning makes the block indentation hard to read [UIView animateWithDuration:1.0                  animations:^{                      // something                  }                  completion:^(BOOL finished) {                      // something                  }];

语言

应当利用US菲律宾语.

应该:

UIColor *myColor = [UIColor whiteColor];

不应该:

UIColor *myColour = [UIColor whiteColor];

<b id=”code-organization”></b>

注释

当须要注释时,注释应该用来解释那段特殊代码为什么要那样做。任何被应用的笺注都不可能不维持最新或被删除。

一般都幸免采取块注释,因为代码尽只怕做到自解释,唯有当断断续续或几行代码时才需求注释。今非昔比:那不应用在扭转文档的笺注

代码协会

在函数分组和protocol/delegate完成中利用#pragma mark -来分类方法,要依照以下一般结构:

#pragma mark - Lifecycle

- (instancetype)init {}
- (void)dealloc {}
- (void)viewDidLoad {}
- (void)viewWillAppear:(BOOL)animated {}
- (void)didReceiveMemoryWarning {}

#pragma mark - Custom Accessors

- (void)setCustomProperty:(id)value {}
- (id)customProperty {}

#pragma mark - IBActions

- (IBAction)submitData:(id)sender {}

#pragma mark - Public

- (void)publicMethod {}

#pragma mark - Private

- (void)privateMethod {}

#pragma mark - Protocol conformance
#pragma mark - UITextFieldDelegate
#pragma mark - UITableViewDataSource
#pragma mark - UITableViewDelegate

#pragma mark - NSCopying

- (id)copyWithZone:(NSZone *)zone {}

#pragma mark - NSObject

- (NSString *)description {}

<b id=”spacing”></b>

命名

Apple命名规则尽只怕百折不挠,特别是与那些相关的memory management
rules(NA宝马X3C)。

长的,描述性的法子和变量命名是好的。

应该:

1 UIButton *settingsButton;

不应该:

1 UIButton *setBut;

五个字符前缀应该平日用在类和常量命名,但在Core
Data的实体名中应被忽视。对于合法的raywenderlich.com书、初学者工具包或课程,前缀’RWT’应该被运用。

常量应该利用驼峰式命名规则,全部的单词首字母大写和添加与类名有关的前缀。

应该:

1 static NSTimeInterval const RWTTutorialViewControllerNavigationFadeAnimationDuration = 0.3;

不应该:

1 static NSTimeInterval const fadetime = 1.7;

特性也是行使驼峰式,但首单词的首字母小写。对质量使用auto-synthesis,而不是手动编写@
synthesize语句,除非你有二个好的说辞。

应该:

1 @property (strong, nonatomic) NSString *descriptiveVariableName;

不应该:

1 id varnm;

空格

  • 缩进使用4个空格,确保在Xcode偏好设置来安装。(raywenderlich.com使用2个空格)
  • 格局大括号和其他大括号(if/else/switch/while
    等.)总是在同一行语句打开但在新行中关闭。

应该:

if (user.isHappy) {
    //Do something
} else {
    //Do something else
}

不应该:

if (user.isHappy)
{
  //Do something
}
else {
  //Do something else
}
  • 在点子之间应当有且只有一行,那样有利于在视觉上更清晰和更便于社团。在艺术内的空白应该分别功效,但常见都抽离出来改成一个新办法。
  • 先行选取auto-synthesis。但如若有必不可少,@synthesize
    @dynamic有道是在促成中各种都声称新的一行。
  • 有道是避免以冒号对齐的章程来调用方法。因为有时候方法签名恐怕有一个以上的冒号和冒号对齐会使代码特别易读。请不要如此这般做,即便冒号对齐的法子包含代码块,因为Xcode的对齐格局令它难以辨认。

应该:

// blocks are easily readable
[UIView animateWithDuration:1.0 animations:^{
  // something
} completion:^(BOOL finished) {
  // something
}];

不应该:

// colon-aligning makes the block indentation hard to read
[UIView animateWithDuration:1.0
                 animations:^{
                     // something
                 }
                 completion:^(BOOL finished) {
                     // something
                 }];

<b id=”comments”></b>

下划线

当使用性质时,实例变量应该选用self.来走访和改动。那就代表全数属性将会视觉效果分歧,因为它们前边都有self.

但有二个特例:在开头化方法里,实例变量(例如,_variableName)应该直接被使用来防止getters/setters潜在的副效用。

一些变量不应当包蕴下划线。

注释

当需求注释时,注释应该用来表明那段特殊代码为什么要这样做。任何被拔取的诠释都必须维持最新或被去除。

貌似都幸免拔取块注释,因为代码尽大概落成自解释,唯有当断断续续或几行代码时才必要注释。今非昔比:这不应用在翻云覆雨文档的诠释

<b id=”naming”></b>

方法

在章程签名中,应该在章程类型(-/+
符号)之后有三个空格。在措施各类段之间应当也有1个空格(符合Apple的风格)。在参数从前应该包括一个全体描述性的关键字来描述参数。

“and”那一个词的用法应该保留。它不应有用于三个参数来验证,就好像initWithWidth:height以下那么些事例:

应该:

1 2 3 4 - (void)setExampleText:(NSString *)text image:(UIImage *)image; - (void)sendAction:(SEL)aSelector to:(id)anObject forAllCells:(BOOL)flag; - (id)viewWithTag:(NSInteger)tag; - (instancetype)initWithWidth:(CGFloat)width height:(CGFloat)height;

不应该:

1 2 3 4 5 -(void)setT:(NSString *)text i:(UIImage *)image; - (void)sendAction:(SEL)aSelector :(id)anObject :(BOOL)flag; - (id)taggedView:(NSInteger)tag; - (instancetype)initWithWidth:(CGFloat)width andHeight:(CGFloat)height; - (instancetype)initWith:(int)width and:(int)height;  // Never do this.

命名

Apple命名规则尽只怕坚韧不拔,特别是与这几个有关的memory management
rules

(NARC)。

长的,描述性的艺术和变量命名是好的。

应该:

UIButton *settingsButton;

不应该:

UIButton *setBut;

多个字符前缀应该时时用在类和常量命名,但在Core
Data的实体名中应被忽视。对于官方的raywenderlich.com书、初学者工具包或课程,前缀’RAV4WT’应该被利用。

常量应该采纳驼峰式命名规则,全部的单词首字母大写和增加与类名有关的前缀。

应该:

static NSTimeInterval const RWTTutorialViewControllerNavigationFadeAnimationDuration = 0.3;

不应该:

static NSTimeInterval const fadetime = 1.7;

属性也是接纳驼峰式,但首单词的首字母小写。对质量使用auto-synthesis,而不是手动编写@
synthesize语句,除非你有七个好的说辞。

应该:

@property (strong, nonatomic) NSString *descriptiveVariableName;

不应该:

id varnm;

<b id=”underscores”></b>

变量

变量尽量以描述性的措施来命名。单个字符的变量命名应该尽量幸免,除了在for()循环。

星号表示变量是指针。例如, NSString *text 既不是 NSString* text 也不是 NSString * text,除了有个别奇特情况下常量。

个体变量 应该尽或许代替实例变量的施用。就算采用实例变量是一种有效的措施,但更偏向于接纳性质来维系代码一致性。

经过应用’back’属性(_variable,变量名后边有下划线)直接访问实例变量应该尽量幸免,除了在早先化方法(initinitWithCoder:,
等…),dealloc 方法和自定义的setters和getters。想通晓有关如何在初叶化方法和dealloc直接使用Accessor方法的更加多消息,查看那里

应该:

1 2 3 4 5 @interface RWTTutorial : NSObject   @property (strong, nonatomic) NSString *tutorialName;   @end

不应该:

1 2 3 @interface RWTTutorial : NSObject {   NSString *tutorialName; }

下划线

当使用性质时,实例变量应该利用self.来拜会和改变。那就象征全体属性将会视觉效果差距,因为它们前边都有self.

但有三个特例:在先导化方法里,实例变量(例如,_variableName)应该一贯被采纳来幸免getters/setters潜在的副效能。

有的变量不应当包罗下划线。

<b id=”methods”></b>

品质天性

具有属性天性应该显式地列出来,有助于新手阅读代码。属性性情的逐条应该是storage、atomicity,与在Interface
Builder连接UI成分时自动生成代码一致。

应该:

1 2 @property (weak, nonatomic) IBOutlet UIView *containerView; @property (strong, nonatomic) NSString *tutorialName;

不应该:

1 2 @property (nonatomic, weak) IBOutlet UIView *containerView; @property (nonatomic) NSString *tutorialName;

NSString应该运用copy 而不是 strong的习性个性。

何以?固然你声美素佳儿个NSString的性质,有人可能传播二个NSMutableString的实例,然后在你没有注意的情状下修改它。

应该:

1 @property (copy, nonatomic) NSString *tutorialName;

不应该:

1 @property (strong, nonatomic) NSString *tutorialName;

方法

在措施签名中,应该在措施类型(-/+
符号)之后有叁个空格。在形式种种段时期应当也有五个空格(符合Apple的品格)。在参数此前应该包涵一个有着描述性的重中之重字来叙述参数。

“and”这些词的用法应该保留。它不应该用于多少个参数来表明,如同initWithWidth:height以下这几个事例:

应该:

- (void)setExampleText:(NSString *)text image:(UIImage *)image;
- (void)sendAction:(SEL)aSelector to:(id)anObject forAllCells:(BOOL)flag;
- (id)viewWithTag:(NSInteger)tag;
- (instancetype)initWithWidth:(CGFloat)width height:(CGFloat)height;

不应该:

-(void)setT:(NSString *)text i:(UIImage *)image;
- (void)sendAction:(SEL)aSelector :(id)anObject :(BOOL)flag;
- (id)taggedView:(NSInteger)tag;
- (instancetype)initWithWidth:(CGFloat)width andHeight:(CGFloat)height;
- (instancetype)initWith:(int)width and:(int)height;  // Never do this.

<b id=”variables”></b>

点符号语法

点语法是一种很有益包装访问方法调用的措施。当您使用点语法时,通过拔取getter或setter方法,属性如故被访问或改动。想驾驭越多,阅读那里

点语法应该总是被用来访问和修改属性,因为它使代码特别从简。[]标记更偏向于用在其他例子。

应该:

1 2 3 NSInteger arrayCount = [self.array count]; view.backgroundColor = [UIColor orangeColor]; [UIApplication sharedApplication].delegate;

不应该:

1 2 3 NSInteger arrayCount = self.array.count; [view setBackgroundColor:[UIColor orangeColor]]; UIApplication.sharedApplication.delegate;

变量

变量尽量以描述性的不二法门来命名。单个字符的变量命名应该尽量防止,除了在for()循环。

星号表示变量是指针。例如, NSString *text 既不是 NSString* text
也不是 NSString * text,除了部分破例景况下常量。

个体变量
应该尽可能代替实例变量的利用。就算采取实例变量是一种有效的格局,但更偏向于采纳性质来保持代码一致性。

透过接纳’back’属性(_variable,变量名前面有下划线)直接访问实例变量应该尽量防止,除了在起头化方法(init,
initWithCoder:, 等…),dealloc
方法和自定义的setters和getters。想了然关于怎么样在起先化方法和dealloc直接运用Accessor方法的越多音讯,查看这里

应该:

@interface RWTTutorial : NSObject

@property (strong, nonatomic) NSString *tutorialName;

@end

不应该:

@interface RWTTutorial : NSObject {
  NSString *tutorialName;
}

<b id=”property-attributes”></b>

字面值

NSStringNSDictionaryNSArray,
和 NSNumber的字面值应该在开创那一个类的不可变实例时被应用。请尤其注意nil值不大概传出NSArrayNSDictionary字面值,因为这么会促成crash。

应该:

1 2 3 4 NSArray *names = @[@"Brian", @"Matt", @"Chris", @"Alex", @"Steve", @"Paul"]; NSDictionary *productManagers = @{@"iPhone": @"Kate", @"iPad": @"Kamal", @"Mobile Web": @"Bill"}; NSNumber *shouldUseLiterals = @YES; NSNumber *buildingStreetNumber = @10018;

不应该:

1 2 3 4 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 *buildingStreetNumber = [NSNumber numberWithInteger:10018];

天性个性

怀有属性天性应该显式地列出来,有助于新手阅读代码。属性本性的逐一应该是storage、atomicity,与在Interface
Builder连接UI成分时自动生成代码一致。

应该:

@property (weak, nonatomic) IBOutlet UIView *containerView;
@property (strong, nonatomic) NSString *tutorialName;

不应该:

@property (nonatomic, weak) IBOutlet UIView *containerView;
@property (nonatomic) NSString *tutorialName;

NSString应该接纳copy 而不是 strong的性质特性。

怎么?尽管你声美赞臣个NSString的质量,有人或许传播3个NSMutableString的实例,然后在您没有注意的情景下修改它。

应该:

@property (copy, nonatomic) NSString *tutorialName;

不应该:

@property (strong, nonatomic) NSString *tutorialName;

<b id=”dot-notation-syntax”></b>

常量

常量是简单重新被应用和无需通过查找和顶替就能便捷修改值。常量应该使用static来声称而不是使用#define,除非显式地使用宏。

应该:

1 2 3 static NSString * const RWTAboutViewControllerCompanyName = @"RayWenderlich.com";   static CGFloat const RWTImageThumbnailHeight = 50.0;

不应该:

1 2 3 #define CompanyName @"RayWenderlich.com"   #define thumbnailHeight 2

点符号语法

点语法是一种很便宜包装访问方法调用的法门。当您使用点语法时,通过动用getter或setter方法,属性仍旧被访问或改动。想询问更加多,阅读这里

点语法应该总是被用于访问和修改属性,因为它使代码尤其简明。[]标志更偏向于用在其余例子。

应该:

NSInteger arrayCount = self.array.count;
view.backgroundColor = [UIColor orangeColor];
[UIApplication sharedApplication].delegate;

不应该:

NSInteger arrayCount = [self.array count];
[view setBackgroundColor:[UIColor orangeColor]];
[[UIApplication sharedApplication] delegate];

<b id=”literals”></b>

枚举类型

当使用enum时,推荐应用新的固化基本类型标准,因为它有更强的类型检查和代码补全。未来SDK有3个宏NS_ENUM()来帮忙和鼓励你利用一定的着力项目。

例如:

1 2 3 4 5 typedef NS_ENUM(NSInteger, RWTLeftMenuTopItemType) {   RWTLeftMenuTopItemMain,   RWTLeftMenuTopItemShows,   RWTLeftMenuTopItemSchedule };

您也得以显式地赋值(显示旧的k-style常量定义):

1 2 3 4 5 6 typedef NS_ENUM(NSInteger, RWTGlobalConstants) {   RWTPinSizeMin = 1,   RWTPinSizeMax = 5,   RWTPinCountMin = 100,   RWTPinCountMax = 500, };

旧的k-style常量定义应该避免只有编写Core Foundation C的代码。

不应该:

1 2 3 4 enum GlobalConstants {   kMaxPinSize = 5,   kMaxPinCount = 500, };

字面值

NSString, NSDictionary, NSArray, 和
NSNumber的字面值应该在开创那个类的不可变实例时被使用。请特别注意nil值不能传出NSArrayNSDictionary字面值,因为这么会导致crash。

应该:

NSArray *names = @[@"Brian", @"Matt", @"Chris", @"Alex", @"Steve", @"Paul"];
NSDictionary *productManagers = @{@"iPhone": @"Kate", @"iPad": @"Kamal", @"Mobile Web": @"Bill"};
NSNumber *shouldUseLiterals = @YES;
NSNumber *buildingStreetNumber = @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 *buildingStreetNumber = [NSNumber numberWithInteger:10018];

<b id=”constants”></b>

Case语句

大括号在case语句中并不是必须的,除非编译器强制须求。当1个case语句包罗多行代码时,大括号应该加上。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 switch (condition) {   case 1:     // ...     break;   case 2: {     // ...     // Multi-line example using braces     break;   }   case 3:     // ...     break;   default:     // ...     break; }

有广大次,当相同代码被多少个cases使用时,2个fall-through应该被接纳。多个fall-through就是在case最终移除’break’语句,那样就可以允许实施流程跳转到下多少个case值。为了代码特别鲜明,贰个fall-through须求注释一下。

1 2 3 4 5 6 7 8 9 10 switch (condition) {   case 1:     // ** fall-through! **   case 2:     // code executed for values 1 and 2     break;   default:     // ...     break; }

当在switch使用枚举类型时,’default’是不要求的。例如:

1 2 3 4 5 6 7 8 9 10 11 12 13 RWTLeftMenuTopItemType menuType = RWTLeftMenuTopItemMain;   switch (menuType) {   case RWTLeftMenuTopItemMain:     // ...     break;   case RWTLeftMenuTopItemShows:     // ...     break;   case RWTLeftMenuTopItemSchedule:     // ...     break; }

常量

常量是便于重新被利用和无需通过搜寻和代表就能高效修改值。常量应该采纳static来声称而不是行使#define,除非显式地使用宏。

应该:

static NSString * const RWTAboutViewControllerCompanyName = @"RayWenderlich.com";

static CGFloat const RWTImageThumbnailHeight = 50.0;

不应该:

#define CompanyName @"RayWenderlich.com"

#define thumbnailHeight 2

<b id=”enumerated-types”></b>

私家属性

村办属性应该在类的落到实处公文中的类伸张(匿名分类)中扬言,命名分类(比如RWTPrivateprivate)应该没有使用除非是扩大其余类。匿名分类应该通过运用<headerfile>+Private.h文件的命名规则揭发给测试。

例如:

1 2 3 4 5 6 7 @interface RWTDetailViewController ()   @property (strong, nonatomic) GADBannerView *googleAdView; @property (strong, nonatomic) ADBannerView *iAdView; @property (strong, nonatomic) UIWebView *adXWebView;   @end

枚举类型

当使用enum时,推荐使用新的定位基本项目标准,因为它有更强的类型检查和代码补全。以往SDK有2个宏NS_ENUM()来援救和鞭策你使用固定的着力类型。

例如:

typedef NS_ENUM(NSInteger, RWTLeftMenuTopItemType) {
  RWTLeftMenuTopItemMain,
  RWTLeftMenuTopItemShows,
  RWTLeftMenuTopItemSchedule
};

你也可以显式地赋值(展现旧的k-style常量定义):

typedef NS_ENUM(NSInteger, RWTGlobalConstants) {
  RWTPinSizeMin = 1,
  RWTPinSizeMax = 5,
  RWTPinCountMin = 100,
  RWTPinCountMax = 500,
};

旧的k-style常量定义应该避免唯有编写Core Foundation C的代码。

不应该:

enum GlobalConstants {
  kMaxPinSize = 5,
  kMaxPinCount = 500,
};

<b id=”case-statements”></b>

布尔值

Objective-C使用YESNO。因为truefalse应当只在CoreFoundation,C或C++代码使用。既然nil解析成NO,所以没有必要在尺度语句比较。不要拿某样东西直接与YES比较,因为YES被定义为1和贰个BOOL能被安装为八位。

这是为了在分化文件保持一致性和在视觉上更为简明而考虑。

应该:

1 2 if (someObject) {} if (![anotherObject boolValue]) {}

不应该:

1 2 3 4 if (someObject == nil) {} if ([anotherObject boolValue] == NO) {} if (isAwesome == YES) {} // Never do this. if (isAwesome == true) {} // Never do this.

如果BOOL属性的名字是1个形容词,属性就能忽视”is”前缀,但要内定get访问器的惯用名称。例如:

1 @property (assign, getter=isEditable) BOOL editable;

文字和例子从那里引用Cocoa Naming Guidelines

Case语句

大括号在case语句中并不是必须的,除非编译器强制须要。当四个case语句包罗多行代码时,大括号应该加上。

switch (condition) {
  case 1:
    // ...
    break;
  case 2: {
    // ...
    // Multi-line example using braces
    break;
  }
  case 3:
    // ...
    break;
  default: 
    // ...
    break;
}

有为数不少次,当相同代码被五个cases使用时,三个fall-through应该被应用。一个fall-through就是在case最终移除’break’语句,那样就可以允许实施流程跳转到下二个case值。为了代码尤其清楚,贰个fall-through需求注释一下。

switch (condition) {
  case 1:
    // ** fall-through! **
  case 2:
    // code executed for values 1 and 2
    break;
  default: 
    // ...
    break;
}

当在switch使用枚举类型时,’default’是不需要的。例如:

RWTLeftMenuTopItemType menuType = RWTLeftMenuTopItemMain;

switch (menuType) {
  case RWTLeftMenuTopItemMain:
    // ...
    break;
  case RWTLeftMenuTopItemShows:
    // ...
    break;
  case RWTLeftMenuTopItemSchedule:
    // ...
    break;
}

<b id=”private-properties”></b>

标准语句

原则语句主体为了预防出错应该运用大括号包围,固然条件语句主体可以不用大括号编写(如,只用一行代码)。那么些错误包含丰裕第2行代码和期望它变成if语句;还有,even
more dangerous
defect只怕暴发在if语句里面一行代码被诠释了,然后下一行代码不知不觉地成为if语句的一部分。除此之外,那种作风与其他标准化语句的品格保持一致,所以越来越便于阅读。

应该:

1 2 3 if (!error) {   return success; }

不应该:

1 2 if (!error)   return success;

1 if (!error) return success;

个人属性

个体属性应该在类的兑现公文中的类扩充(匿名分类)中注解,命名分类(比如RWTPrivateprivate)应该没有使用除非是增加其他类。匿名分类应该经过选拔<headerfile>+Private.h文件的命名规则揭示给测试。

例如:

@interface RWTDetailViewController ()

@property (strong, nonatomic) GADBannerView *googleAdView;
@property (strong, nonatomic) ADBannerView *iAdView;
@property (strong, nonatomic) UIWebView *adXWebView;

@end

<b id=”booleans”></b>

元朔操作符

当要求增强代码的清晰性和简洁性时,长富操作符?:才会接纳。单个条件求值平常必要它。四个规格求值时,假诺运用if言辞或重构成实例变量时,代码会愈来愈易读。一般的话,最好使用伊利操作符是在按照规则来赋值的景色下。

Non-boolean的变量与某东西相比较,加上括号()会增高可读性。若是被比较的变量是boolean类型,那么就不须要括号。

应该:

1 2 3 4 5 NSInteger value = 5; result = (value != 0) ? x : y;   BOOL isHorizontal = YES; result = isHorizontal ? x : y;

不应该:

1 result = a > b ? x = c > d ? c : d : y;

布尔值

Objective-C使用YESNO。因为truefalse有道是只在CoreFoundation,C或C++代码使用。既然nil解析成NO,所以没有须要在尺度语句相比。不要拿某样东西直接与YES比较,因为YES被定义为1和2个BOOL能被安装为五人。

这是为了在不一致文件保持一致性和在视觉上更是简洁而考虑。

应该:

if (someObject) {}
if (![anotherObject boolValue]) {}

不应该:

if (someObject == nil) {}
if ([anotherObject boolValue] == NO) {}
if (isAwesome == YES) {} // Never do this.
if (isAwesome == true) {} // Never do this.

如果BOOL本性的名字是1个形容词,属性就能忽视”is”前缀,但要内定get访问器的惯用名称。例如:

@property (assign, getter=isEditable) BOOL editable;

文字和例子从那边引用Cocoa Naming
Guidelines

<b id=”conditionals”></b>

Init方法

Init方法应该依据Apple生成代码模板的命名规则。重临类型应该利用instancetype而不是id

1 2 3 4 5 6 7 - (instancetype)init {   self = [super init];   if (self) {     // ...   }   return self; }

翻看关于instancetype的小说Class Constructor Methods

条件语句

标准语句主体为了防止出错应该利用大括号包围,固然条件语句主体可以不用大括号编写(如,只用一行代码)。这么些不当包涵丰盛第1行代码和期望它成为if语句;还有,even
more dangerous
defect
可能发生在if语句里面一行代码被诠释了,然后下一行代码不知不觉地改成if语句的一有的。除此之外,那种作风与此外规格语句的风格保持一致,所以越发简单阅读。

应该:

if (!error) {
  return success;
}

不应该:

if (!error)
  return success;

if (!error) return success;

<b id=”ternary-operator”></b>

类构造方法

当类构造方法被采用时,它应有回到类型是instancetype而不是id。那样保证编译器正确地想见结果类型。

1 2 3 @interface Airplane + (instancetype)airplaneWithType:(RWTAirplaneType)type; @end

有关越多instancetype新闻,请查看NSHipster.com

大年底一操作符

当要求升高代码的清晰性和简洁性时,三元操作符?:才会利用。单个条件求值平常必要它。多个原则求值时,假诺应用if言语或重构成实例变量时,代码会愈发易读。一般的话,最好使用三元操作符是在依据标准来赋值的情事下。

Non-boolean的变量与某东西比较,加上括号()会拉长可读性。借使被比较的变量是boolean类型,那么就不须求括号。

应该:

NSInteger value = 5;
result = (value != 0) ? x : y;

BOOL isHorizontal = YES;
result = isHorizontal ? x : y;

不应该:

result = a > b ? x = c > d ? c : d : y;

<b id=”init-methods”></b>

CGRect函数

当访问CGRect里的xywidth,
或 height时,应该利用CGGeometry函数而不是一向通过社团体来访问。引用Apple的CGGeometry:

在这些参考文档中享有的函数,接受CGRect结构体作为输入,在测算它们结果时隐式地规范那个rectangles。由此,你的应用程序应该防止直接访问和改动保存在CGRect数据结构中的数据。相反,使用这一个函数来操纵rectangles和收获它们的天性。

应该:

1 2 3 4 5 6 7 CGRect frame = self.view.frame;   CGFloat x = CGRectGetMinX(frame); CGFloat y = CGRectGetMinY(frame); CGFloat width = CGRectGetWidth(frame); CGFloat height = CGRectGetHeight(frame); CGRect frame = CGRectMake(0.0, 0.0, width, height);

不应该:

1 2 3 4 5 6 7 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; CGRect frame = (CGRect){ .origin = CGPointZero, .size = frame.size };

黄金路线

当使用条件语句编码时,左手边的代码应该是”golden” 或
“happy”路径。也等于并非嵌套if话语,几个重返语句也是OK。

应该:

1 2 3 4 5 6 7 - (void)someMethod {   if (![someOther boolValue]) {     return;   }     //Do something important }

不应该:

1 2 3 4 5 - (void)someMethod {   if ([someOther boolValue]) {     //Do something important   } }

错误处理

当方法通过引用来回到三个不当参数,判断重回值而不是荒谬变量。

应该:

1 2 3 4 NSError *error; if (![self trySomethingWithError:&error]) {   // Handle Error }

不应该:

1 2 3 4 5 NSError *error; [self trySomethingWithError:&error]; if (error) {   // Handle Error }

在中标的景况下,有些Apple的APIs记录垃圾值(garbage
values)到错误参数(假使non-NULL),那么判断错误值会造成false负值和crash。

单例格局

单例对象应该使用线程安全方式来成立共享实例。

1 2 3 4 5 6 7 8 9 10 + (instancetype)sharedInstance {   static id sharedInstance = nil;     static dispatch_once_t onceToken;   dispatch_once(&onceToken, ^{     sharedInstance = [[self alloc] init];   });     return sharedInstance; }

那会防止possible and sometimes prolific crashes.

换行符

换行符是二个很要紧的大旨,因为它的品格指南首要为了打印和网上的可读性。

例如:

1 self.productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:productIdentifiers];

一行相当长的代码应该分为两行代码,下一行用多个空格隔开。

1 2 self.productsRequest = [[SKProductsRequest alloc]   initWithProductIdentifiers:productIdentifiers];

Xcode工程

物理文件应该与Xcode工程文件保持同步来幸免文件增添。任何Xcode分组的开创应该在文件系统的文书展示。代码不仅是基于类型来分组,而且还可以依据功能来分组,那样代码特别明显。

尽大概在target的Build Settings打开”Treat Warnings as
Errors,和启用以下additional
warnings。假如你必要忽略特殊的警示,使用 Clang’s pragma feature。

别的Objective-C编码规范

假定我们的编码规范不切合您的气味,能够查看其余的编码规范:

  • Robots & Pencils
  • New York Times
  • Google
  • GitHub
  • Adium
  • Sam Soffes
  • CocoaDevCentral
  • Luke Redpath
  • Marcus Zarra

    itemprop=”url”>http://www.bkjia.com/IOSjc/1011691.html id=”indexUrl” itemprop=”indexUrl”>www.bkjia.com id=”isOriginal” itemprop=”isOriginal”>true id=”isBasedOnUrl”
    itemprop=”isBasedOnUrl”>http://www.bkjia.com/IOSjc/1011691.html id=”genre” itemprop=”genre”>TechArticle itemprop=”description”>Ray Wenderlich 的
    Objective-C编码规范,raywenderlich
    由于本身正在预备模仿饿了么这些app,到时只怕有点iOS开发者出席进来。那时假诺各个人的Obje…

Init方法

Init方法应该遵循Apple生成代码模板的命名规则。再次回到类型应该利用instancetype而不是id

- (instancetype)init {
  self = [super init];
  if (self) {
    // ...
  }
  return self;
}

翻看关于instancetype的稿子Class Constructor
Methods

<b id=”class-constructor-methods”></b>

类构造方法

当类构造方法被利用时,它应该回到类型是instancetype而不是id。那样保障编译器正确地测算结果类型。

@interface Airplane
+ (instancetype)airplaneWithType:(RWTAirplaneType)type;
@end

有关更多instancetype音讯,请查看NSHipster.com

<b id=”cgrect-functions”></b>

CGRect函数

当访问CGRect里的x, y, width, 或
height时,应该运用CGGeometry函数而不是直接通过结构体来访问。引用Apple的CGGeometry:

在这一个参考文档中具有的函数,接受CGRect结构体作为输入,在计算它们结果时隐式地条件那么些rectangles。因此,你的应用程序应该幸免直接访问和改动保存在CGRect数据结构中的数据。相反,使用这个函数来操纵rectangles和得到它们的特点。

应该:

CGRect frame = self.view.frame;

CGFloat x = CGRectGetMinX(frame);
CGFloat y = CGRectGetMinY(frame);
CGFloat width = CGRectGetWidth(frame);
CGFloat height = CGRectGetHeight(frame);
CGRect frame = CGRectMake(0.0, 0.0, width, height);

不应该:

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;
CGRect frame = (CGRect){ .origin = CGPointZero, .size = frame.size };

<b id=”golden-path”></b>

金子路线

当使用原则语句编码时,左手边的代码应该是”golden” 或
“happy”路径。相当于不用嵌套if言语,七个重返语句也是OK。

应该:

- (void)someMethod {
  if (![someOther boolValue]) {
    return;
  }

  //Do something important
}

不应该:

- (void)someMethod {
  if ([someOther boolValue]) {
    //Do something important
  }
}

<b id=”error-handling”></b>

错误处理

当方法通过引用来回到二个错误参数,判断再次来到值而不是不当变量。

应该:

NSError *error;
if (![self trySomethingWithError:&error]) {
  // Handle Error
}

不应该:

NSError *error;
[self trySomethingWithError:&error];
if (error) {
  // Handle Error
}

在功成名就的景观下,有些Apple的APIs记录垃圾值(garbage
values)到不当参数(假若non-NULL),那么判断错误值会促成false负值和crash。

<b id=”singletons”></b>

单例形式

单例对象应该采用线程安全情势来成立共享实例。

+ (instancetype)sharedInstance {
  static id sharedInstance = nil;

  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    sharedInstance = [[self alloc] init];
  });

  return sharedInstance;
}

那会防止possible and sometimes prolific
crashes
.

<b id=”line-breaks”></b>

换行符

换行符是2个很紧要的大旨,因为它的风骨指南首要为了打印和网上的可读性。

例如:

self.productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:productIdentifiers];

一行不短的代码应该分为两行代码,下一行用四个空格隔开。

self.productsRequest = [[SKProductsRequest alloc] 
  initWithProductIdentifiers:productIdentifiers];

<b id=”xcode-project”></b>

Xcode工程

大体文件应当与Xcode工程文件保持同步来幸免文件增添。任何Xcode分组的创设应该在文件系统的文件突显。代码不仅是基于类型来分组,而且还足以依照功能来分组,那样代码越发分明。

尽心尽力在target的Build Settings打开”Treat Warnings as
Errors,和启用以下additional
warnings
。如若你须要忽略特殊的警示,使用
Clang’s pragma
feature

别的Objective-C编码规范

假使我们的编码规范不吻合您的意气,可以查阅其他的编码规范: