iOS代码规范

Language 语言

使用美式英语

Preferred:
UIColor *myColor = [UIColor whiteColor];
Not Preferred:
1.UIColor *myColour = [UIColor whiteColor];//Colour 英式英语
2.UIColor *myYanSe = [UIColor whiteColor];//YanSe
...

Code Organization 代码结构

使用 #pragma mark - 去分类 methods组、protocol/delegate...

#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 {}

Spacingkon 空格

方法括号和其他括号(if / else / switch / while等)始终在语句相同的行上打开,但在新行上关闭。

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

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

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

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

Comments 注释

1.注释用于特定代码片段起得作用
2.使用的任何注释都必须保持最新或刪除。
3.尽量避免使用大篇幅的注释块,代码应该是尽可能的自我说明与记录,只需要是间歇性的几行解释

Naming 命名

驼峰法
UILabel *myNameLabl = [UILabel new];

冗長的描述性方法和变量名称都很好,不要为了简单而失去可读性
Preferred:
UIButton *settingsButton;

Not Preferred:
UIButton *setBut;

对于类名和常量,应始终三个字母的前缀(apple申明过 保留所有两个字母前缀的使用权,如果哪天apple使用了,你的代码就凉了);对于Core Data实体名称可以省略前缀。
eg:假设简书前缀是 JST(JianShuTeam),不应该是JS
Preferred:
static NSTimeInterval const JSTTutorialViewControllerNavigationFadeAnimationDuration = 0.3;

Not Preferred:
static NSTimeInterval const 
 JSTutorialViewControllerNavigationFadeAnimationDuration = 0.3;
static NSTimeInterval const fadetime = 1.7;

属性开头应是小写字母,类名开头应是大写;并且符合驼峰法
Preferred:
@property (strong, nonatomic) NSString *descriptiveVariableName;
interface JSTManangeCenter :NSObject

Underscores 下划线

访问属性时应尽可能使用self. 访问,而不是使用下划线访问实例变量
但是:內部初始化器,应该直接使用支持实例变量(即_variableName)來避免getter / setter的任何潜在副作用。
局部变量不应该包含下划线

Methods 方法

在方法签名中,方法类型( - / +符号)后面应该有一个空格。
方法段之间应该有一个空格(匹配Apple的样式)。
始终包含一个关键字,并在描述参数的参数之前用单词描述。
不使用 and或者少使用

Preferred:
- (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;

Not Preferred:
-(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.

Variables 变量

变量应该尽可能的描述;
避免使用单个单词

应尽可能使用私有属性代替实例变量。尽管使用实例变量是一种有效的处理方式,但通过统一属性,我們的代码將更加一致。

Preferred:
@interface RWTTutorial : NSObject
@property (strong, nonatomic) NSString *tutorialName;
@end

Not Preferred:
@interface RWTTutorial : NSObject {
  NSString *tutorialName;
}

指针*属于变量

Preferred:
NSString *text 
Not Preferred:
not NSString* text or NSString * text

Property Attributes 属性 前缀

像weak、strong、nonatomic 这种Property Attributes,应该明确列出,并在阅读代码时帮助新程序员。顺序一般是强弱引用然后是原子性。

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

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

具有可变对应物的属性(NSString.NSArray)应该使用Copy 而不是Strong

Preferred:
@property (copy, nonatomic) NSString *tutorialName;

Not Preferred:
@property (strong, nonatomic) NSString *tutorialName;

Dot-Notation Syntax 点号语法

点号(.)语法应始终用于读写属性,因为它使代码更简洁。在所有其他情况下,首选括号([])。

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

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

Literals 字面量

每当创建NSString,NSDictionary,NSArray和NSNumber这些对象的不可变实例时,都应使用字面量。特別注意nil值不能传给NSArray和NSDictionary,会导致崩溃。

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

Not Preferred:
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];

Constants 常量

除非明确用作宏,否則应将常量生命为静态常量而不是#defines。

Preferred:
static NSString * const RWTAboutViewControllerCompanyName = @"RayWenderlich.com";
static CGFloat const RWTImageThumbnailHeight = 50.0;

Not Preferred:
#define CompanyName @"RayWenderlich.com"
#define thumbnailHeight 2

Enumerated Types 枚举类型

使用新的NS_ENUM 去声明,并且加上工程前缀

Preferred:
typedef NS_ENUM(NSInteger, JSTLeftMenuTopItemType) {
  JSTLeftMenuTopItemMain,
  JSTLeftMenuTopItemShows,
  JSTLeftMenuTopItemSchedule
};
typedef NS_ENUM(NSInteger, JSTGlobalConstants) {
  JSTPinSizeMin = 1,
  JSTPinSizeMax = 5,
  JSTPinCountMin = 100,
  JSTPinCountMax = 500,
};

Not Preferred:
enum GlobalConstants {
  kMaxPinSize = 5,
  kMaxPinCount = 500,
};

Case Statements Case语句

除非由编译器强制执行,否则case语句不需要括號。 当某个case包含多行语句时,应添加大括号;多个条件执行相同语句时,去掉break 会有 fall-through贯穿效果

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

使用枚举类型作为开关时,不需要“ default”

JSTLeftMenuTopItemType menuType = JSTLeftMenuTopItemMain;
switch (menuType) {
  case JSTLeftMenuTopItemMain:
    // ...
    break;
  case JSTLeftMenuTopItemShows:
    // ...
    break;
  case JSTLeftMenuTopItemSchedule:
    // ...
    break;
}

Private Properties 私有属性

私有属性应该申明在类扩展(匿名分类)中的.m文件中

For Example:
@interface RWTDetailViewController ()
@property (strong, nonatomic) GADBannerView *googleAdView;
@property (strong, nonatomic) ADBannerView *iAdView;
@property (strong, nonatomic) UIWebView *adXWebView;

@end

Booleans 布尔值

OC使用 YES和NO,因此true和false应该用于CoreFoundation,C,C++
由于nil解析为NO,因此无需在条件下进行比较

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

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

Conditionals 條件語句

有条件的主体应该总是使用大括号,即使条件主体可以没有大括号(例如,它只是一行)来防止错误。

Preferred:
if (!error) {
  return success;
}

Not Preferred:
if (!error)
  return success;
or
if (!error) return success;

Ternary Operator 三元运算符

三元运算符?:只应在增加清晰度或代码整洁度时使用。 一个条件通常都应该被评估。 评估多个条件通常更容易理解为if语句,或重构为实例变量。 通常,三元运算符的最佳用途是在赋值变量和决定使用哪个值期间。

应该将非布尔变量与某些内容进行比较,并添加括号以提高可读性。 如果要比较的变量是布尔类型,则不需要括号。

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

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

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

Init Methods 初始化

Init方法应遵循Apple生成的代码模板提供的约定。还应使用返回类型“instancetype”而不是“id”。

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

Class Constructor Methods 类构造方法

在使用类构造函数方法的地方,这些方法应始终返回'instancetype'类型而不是'id'。 这可确保编译器正确推断结果类型。

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

@end

CGRect Functions CGRect功能

访问CGRect的x,y,width或height时,始终使用CGGeometry函数而不是直接的struct member访问。 来自Apple的CGGeometry参考:

Preferred:
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);

Not Preferred:
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 Path 黄金路径

使用条件编码时,代码的左边距应为“黄金”或“快乐”路径。 也就是说,不要嵌套if语句。 多个return语句都可以。

Preferred:
- (void)someMethod {
  if (![someOther boolValue]) {
    return;
  }
  //Do something important
}

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

Error handling 错误处理

当方法通过引用返回错误参数时,请打开返回的值,而不是错误变量。
在成功的情况下,Apple的某些API会将垃圾值写入错误参数(如果为非NULL),因此启用错误可能会导致错误否定(并随后崩溃)。

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

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

Singletons 单例

Singleton对象应使用线程安全模式来创建其共享实例。

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

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

  return sharedInstance;
}

Line Breaks 换行

换行注重于可读性

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

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

Smiley Face 笑脸

笑脸是某些coder非常突出的风格特征! 拥有正确的微笑非常重要,这标志着编码主题的巨大快乐和兴奋。 使用末端方括号是因为它代表了能够使用ascii艺术捕获的最大微笑。 如果使用末端括号,则表示半心半意的微笑,因此不是优选的。

Preferred:
:]

Not Preferred:
:)

Xcode project

物理文件应与Xcode项目文件保持同步,以避免文件蔓延。 创建的任何Xcode组都应该由文件系统中的文件夹反映出来。 代码不仅应按类型分组,还应按功能分组,以便更清晰。

如果这篇文章对您有用,烦请点个赞,这是对小弟最大的支持,谢谢

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容

  • 这是16年5月份编辑的一份比较杂乱适合自己观看的学习记录文档,今天18年5月份再次想写文章,发现简书还为我保存起的...
    Jenaral阅读 2,729评论 2 9
  • 这里有些关于编码风格Apple官方文档,如果有些东西没有提及,可以在以下文档来查找更多细节: The Object...
    Loki9527阅读 392评论 0 0
  • 一、命名规范 1、统一要求含义清楚,尽量做到不需要注释也能了解其作用,若做不到,就加注释,使用全称,不使用缩写。 ...
    Untils阅读 544评论 0 0
  • 概要 Objective-C是一门面向对象的动态编程语言,主要用于编写iOS和Mac应用程序。关于Objectiv...
    DreamMmMmM阅读 1,146评论 0 7
  • 朗境科技 移动团队 郎镜通代码规范指南 介绍 关于这个编程语言的所有规范,如果这里没有写到,那就在苹果的文档里:...
    百事小武阅读 838评论 1 2