目录

  

  注释

1.1  多行注释

1.2  单行注释

1.3  函数的注释

  命名

2.1  常量的命名

2.2  函数的命名

2.3  变量的命名

2.3.1  成员变量

2.3.2  公共变量命名

2.3.3  实例变量命名

2.4  图片的命名

2.5  类的命名

2.5.1分类名

2.6  条件语句

2.7  变量

  下划线

  Immutable 实例初始化

  类型

5.1  CGRect 函数

5.2  常量

5.3  枚举类型

5.4  布尔变量

5.5  单例

5.6  数字

6  代码组织

7  判断语句

8  私有方法

  git commit 格式

9.1  参考规范

9.2  格式

10函数声明和定义

11方法调用

协议

Blocks

 

 

iOS编码规范参考

 

  注释

 

建议使用VVDocumenter插件

 

1.1  多行注释

 

格式:

 

/**

 

 注释内容

 */

1.2  单行注释

 

格式:

 

///在对文件、类、函数进行注释时推荐使用多行注释,在函数体内对代码块进行注释时,使用单行注释

1.3  函数的注释

 

函数注释的格式为

 

/**

 *  @brief

 *  @param

 *  @return

 **/

在brief中需要写明函数的主要功能、注意事项

在param中需要写明函数的变量类型、变量的作用

在return中需要写明函数的返回类型、返回值的作用

如有其他需要说明的地方,可以在@return后面添加新项。如

/**

 *  @brief

 *  @param

 *  @return

 *  @warning

 **/

 

/**

 *  @brief      上传图片。上传成功后会自动将图片放入缓存,缓存的key为图片的url

 *  @param      UIImage,需要上传的图片

 *  @return    void

 *  @blocks

 *              success:返回的NSDictionary中包含服务器的response信息,包括图片id(id),url(url),宽度(width),高度(height)。使用括号中的名称从NSDictionary中获取。

 *              failed:返回error

 **/

  命名

 

2.1  常量的命名

 

(如宏、枚举、静态局部变量等)应该以小写字母k开头,使用混合大小写的格式来分隔单词。

 

2.2  函数的命名

 

函数名应该已小写字母开头,并混合大小写,其中的每个参数都应该是小写字母开头,读起来应该像句子一样,访问器方法应该与他们getting的成员变量的名字一样,但不应该以get作为前缀,如:

 

- (id)getDelegate;    //avoid

- (id)delegate;       //good

2.3  变量的命名

2.3.1  成员变量

成员变量应该以小写字母开头,并以下划线作为后缀,如usernameTextField_,使用KVO/KVC绑定成员变量时,可以以一个下划线为前缀。

 

2.3.2  公共变量命名

小写字母开头。如:imageView;

 

2.3.3  实例变量命名

 

() 私有变量

应该以下划线开头。如:_addButton

 

() 常量命名

以小写k开头,混合大小写。如:kInvalidHandle, kWritePerm

 

2.4  图片的命名

 

应该已“模块+功能+作用+样式”的形式

 

如:

message_private_at_button_bg_normal.png

2.5  类的命名

 

类名、分类名、协议名应该以大写字母开始,并混合小写字母来分隔单词,应该已“模块+功能+子功能”的方式:

 

如:MessagePrivateAtsomebody

应用级的类,应避免不用前缀,跨应用级的类,应使用前缀, objc 如:GTMSendMessage

 

2.5.1  分类名

 

类别名应该有两三个字母作为前缀已表示为某项目的一部分,并且包含所扩展的类的名字,如我们要创建一个NSString的类别以解析,我们将类别放在一个名为GTMNSString+Parsing.h的文件中。类别名本身为GTMStringParsingAdditions(类别名与文件名不同是为了让文件可以包含更多相同功能的扩展)类名与包含类别名之间应一个空格分隔。

 

如:

//NSString 为要扩展的类名, GTMStringParsingAdditions为类别名

@interface NSString (GTMStringParsingAdditions)

- (NSString *)gtm_foobarString;

@end

 

@interface FoobarViewController ()

@property(nonatomic, retain) NSView *dongleView;

- (void)performLayout;

@end

注意事项

 

2.6  条件语句

 

为避免错误,条件语句体必须使用大括号,即便语句体中的语句可以不必使用大括号(比如只有一行语句)。常见的错误包括在不使用大括号的情况下添加第二行语句,以为它属于if语句的一部分。此外,更可怕的事情是,如果条件语句中的代码行被注释,则本不术语条件语句的下一行代码将变成条件语句的一部分。此外,这种编码风格和所有其它条件语句均保持一致。

 

如:

if (!error) {

    return success;

}

2.7  变量

 

变量的命名应尽可能具有自解释性。除了在for()循环语句中,应避免使用单个字母变量名称。除非是常量,星号应紧贴变量名称表示指向变量的指针, objc 如: NSString *text;

 

应尽可能使用属性定义替代单一的实例变量。避免在初始化方法,dealloc方法和自定义的setter和getter方法中直接读取实例变量参数(init,initWithCoder:,等等)

 

如:

@interface NYTSection: NSObject

 

@property (nonatomic) NSString *headline;

 

@end

 

应尽量避免下面的方式:

 

@interface NYTSection : NSObject {

    NSString *headline;

}

  下划线

 

当使用属性变量时,应通过self.来获取和更改实例变量。这就意味着所有的属性将是独特的,因为它们的名称前会加上self。本地变量名称中不应包含下划线

 

如:

self.imgView.backgroundColor = [UIColor black];

 

而尽量避免:

 

  Immutable实例初始化

 

在创建NSString,NSDictionary,NSArray和NSNumber等对象的immutable实例时,应使用字面量。需要注意的是,不应将nil传递给NSArray和NSDictionary字面量,否则会引起程序崩溃。所以在存入数据到NSArray和NSDictionary时也要判断一下数据是否是nil。

 

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 = [NSArrayarrayWithObjects:@"Brian", @"Matt", @"Chris", @"Alex", @"Steve", @"Paul", nil];

NSDictionary *productManagers = [NSDictionary dictionaryWithObjectsAndKeys: @"Kate", @"iPhone", @"Kamal", @"iPad", @"Bill", @"Mobile Web", nil];

NSNumber *shouldUseLiterals = [NSNumber numberWithBool:YES];

];

  类型

 

最好用NSInteger和NSUInteger而不是用int,long。其他的float同理。

 

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

5.2  常量

 

相对字符串字面量或数字,我们更推荐适用常量。应使用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

5.3  枚举类型

 

在使用enum的时候,推荐适用最新的fixed underlying type(WWDC session - Modern Objective-C)规范,因为它具备更强的类型检查和代码完成功能。

 

如:

typedef NS_ENUM(NSInteger, NYTAdRequestState) {

    NYTAdRequestStateInactive,

    NYTAdRequestStateLoading

};

5.4  布尔变量

 

因为nil将被解析为NO,因此没有必要在条件语句中进行比较。永远不要将任何东西和YES进行直接比较,因为YES被定义为1,而一个BOOL变量可以有8个字节。

 

如:

if (!someObject) {

}

 

if (isAwesome)

 

if (![someObject boolValue])

 

不恰当:

if (someObject == nil) {

}

 

if ([someObject boolValue] == NO)

 

if (isAwesome == YES) // Never do this.

如果一个BOOL属性使用形容词来表达,属性将忽略’is’前缀,但会强调惯用名称。例如:

 

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

5.5  单例

 

在创建单例对象的共享实例时,应使用线程安全模式。

 

如:

(instancetype)sharedInstance {

    static id sharedInstance = nil;

    

    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

        sharedInstance = [[self alloc] init];

    });

    

    return sharedInstance;

}

5.6  数字

 

尽量避免数字固定为某个类型如:写5而不写5.0,5.3而不写5.3f)

 

6  代码组织

 

用 #pragma mark来将方法分类,这个非常有效,当你用快捷键Control+6可以高效的寻找到自己想要跳转到的方法

 

//#pragma mark Properties

 

@dynamic someProperty;

 

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

 

#pragma mark Lifecycle

 

+ (id)objectWithThing:(id)thing {}

- (id)init {}

 

#pragma mark Drawing

 

#pragma mark UItableView delegate

 

#pragma mark UITableView datasource

 

- (void)drawRect:(CGRect) {}

 

#pragma mark Another functional grouping

 

#pragma mark GHSuperclass

 

- (void)someOverriddenMethod {}

 

#pragma mark NSCopying

 

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

 

#pragma mark NSObject

 

- (NSString *)description {}

7  判断语句

 

if和else应该和左大括号在同一行

 

如:

if (button.enabled) {

    // Stuff

} else if (otherButton.enabled) {

    // Other stuff

} else {

    // More stuf

}

Switch 也是一样

 

如:

switch (something.state) {

    case : {

        // Something

        break;

    }

    

    case : {

        // Something

        break;

    }

    

    case :

    case : {

        // Something

        break;

    }

    

    default: {

        // Something

        break;

    }

}

Import

 

在类的头文件中需要引用其他的类的时候,需要用@class这个关键字,这样能减少类与类之间的依赖。

 

如:

store.h:

 

#import <Foundation/Foundation.h>

#import <CoreData/CoreData.h>

 

@class User;

 

@interface Store : NSManagedObject

 

@property (nonatomic, retain) User *user;

 

@end

 

Store.m:

 

#import "Store.h"

 

#import "User.h"

 

@implementation Store

 

//doSomething

 

@end

8  私有方法

 

关于私有方法,苹果官方建议呢是使用统一的前缀来分组和辨识。但是千万不用下划线来作为前缀来命名,或者你可以在前缀前添加一些特殊的标识。

 

  git commit 格式

 

可以参考google开源项目的Commit 规范

 

9.1  参考规范

 

添加了新功能 feat(大模块+子模块):#例如实现了某个具体功能

修改了某些功能 change(大模块+子模块):#例如修改了某个具体的功能

修复了某个Bug fix_bug(大模块+子模块):#修复了什么的bug,最好写上*原因*和*解决方法*。

比较大的改动 ``` broken_change(): before:

 

after: ```

 

修改了文档 docs():

 

修改了格式 style():

 

添加了一些测试 test(大模块+子模块):

 

一些杂项,比如像解决工程编译错误等问题之后的修改 chore():

 

对又有代码的重构 refactor(大模块+子模块):

 

9.2  格式

 

一行代码的长度不能超过80个字母

 

10  函数声明和定义:

 

“-”或“+”和返回类型之间应该有一个空格

 

如:

- (void)doSomethingWithString:(NSString *)theString {

    ...

}

方法大括号和其它大括号(比如if/else/switch/while等等)应在语句的同一行开始,而在新的一行关闭。

 

if (user.isHappy) {

    //Do something

}

else {

    //Do something else

}

当有多个参数的时,如果参数太多超过一行,则应该将每个参数分行,并且冒号对齐

 

如:

- (void)doSomethingWith:(GTMFoo *)theFoo

rect:(NSRect)theRect

interval:(float)theInterval {

    ...

}

当第一个参数短于其他参数的时候,分行时每行至少要缩进4个空格

 

longKeyword:(NSRect)theRect

evenLongerKeyword:(float)theInterval

error:(NSError **)theError {

    ...

}

  方法调用

 

方法调用应该和方法声明的时候一个格式,要么所有参数放在一行里:

 

[myObject doFooWith:arg1 name:arg2 error:arg3];

要么每一行一个参数:

 

如:

[myObject doFooWith:arg1

               name:arg2

              error:arg3];

当第一个参数短语其他参数的时候,分行是每行至少要缩进4个空格:

 

如:

[myObj short:arg1

 longKeyword:arg2

 evenLongerKeyword:arg3

 error:arg4];

 

@public和@private前面为一个空格

 

如:

@interface MyClass : NSObject{

@public

    …

@private

}

@end

  协议

 

类型与协议名之间不要空格

 

如:

@interface MyProtocoledClass : NsObject<NSWindowDelegate> {

@private

    id<MyFancyDelegate> _delegate;

}

-  (void)setDelegate:(id<MyFancyDelegate>)aDelegate;

@end

  Blocks

 

在一行的情况

如:

[operation setCompletionBlock:^{ [self onOperationDone]; }];

 

//block 在新的行里,需要缩进四个空格

[operation setCompletionBlock:^{

    [self.delegate newDataAvailable];

}];

 

dispatch_async(_fileIOQueue, ^{

    NSString* path = [self sessionFilePath];

    if (path) {

        // ...

    }

});

//有参数的block,|(SessionWindow *window)|与|{|之间有一个空格

如:

[[SessionService sharedService]

 loadWindowWithCompletionBlock:^(SessionWindow *window) {

     if (window) {

         [self windowDidLoad:window];

     } else {

         [self errorLoadingWindow];

     }

 }];

 

//block 中有参数且不能在一行中显示

//要行与行之间要相对有四个空格

[[SessionService sharedService]

 loadWindowWithCompletionBlock:

 ^(SessionWindow *window) {

     if (window) {

         [self windowDidLoad:window];

     } else {

         [self errorLoadingWindow];

     }

 }];

 

//很长的block可以被定义不在一行里

void (^largeBlock)(void) = ^{

    // ...

};

[_operationQueue addOperationWithBlock:largeBlock];

 

 

 

 

 

 

iOS编码规范参考的更多相关文章

  1. iOS编码规范(简版)

    1. 总体指导原则 [规则1-1]首先是为人编写程序,其次才是计算机. 说明:这是软件开发的基本要点,软件的生命周期贯穿产品的开发.测试.生产.用户使用.版本升级和后期维护等长期过程,只有易读.易维护 ...

  2. iOS编码规范

      The official raywenderlich.com Objective-C style guide.   This style guide outlines the coding con ...

  3. iOS 编码规范

    Coding Guidelines for Cocoa https://developer.apple.com/library/prerelease/content/documentation/Coc ...

  4. iOS 注释的5要3不要和编码规范的26个方面

    注释 代码注释,可以说是比代码本身更重要.这里有一些方法可以确保你写在代码中的注释是友好的: 不要重复阅读者已经知道的内容 能明确说明代码是做什么的注释对我们是没有帮助的. // If the col ...

  5. Objective-C编码规范:26个方面解决iOS开发问题

    介绍 我们制定Objective-C编码规范的原因是我们能够在我们的书,教程和初学者工具包的代码保持优雅和一致.即使我们有很多不同的作者来完成不同的书籍. 这里编码规范有可能与你看到的其他Object ...

  6. 【安全开发】IOS安全编码规范

    申明:本文非笔者原创,原文转载自:https://github.com/SecurityPaper/SecurityPaper-web/blob/master/_posts/2.SDL%E8%A7%8 ...

  7. [iOS翻译]Cocoa编码规范

        简介: 本文整理自Apple文档<Coding Guidelines for Cocoa>.这份文档原意是给Cocoa框架.插件及公共API开发者提供一些编码指导,实质上相当于Ap ...

  8. OWASP安全编码规范快速参考指南

    0x00 原则 概览 开发安全的软件需要对安全原则有基本的了解.虽然对于安全原则的全面评估超出了本指南的范围,但是我们还是提供了一个快速的概览.软件安全的目标是要维护信息资源的 保密性 ,  完整性 ...

  9. ios之编码规范具体说明

    iOS代码规范: 所有代码规范所有遵循苹果sdk的原则,不清楚的请訪问苹果SDK文档或下载官方Demo查看. 1.project部分: 将项目中每一个功能模块相应的源文件放入同一目录下,使用虚拟目录. ...

随机推荐

  1. leetcode刷题笔记172 阶乘后的零

    题目描述: 给定一个整数 n,返回 n! 结果尾数中零的数量. 示例1: 输入: 输出: 解释: ! = , 尾数中没有零. 示例2: 输入: 输出: 解释: ! = , 尾数中有 个零. 说明: 你 ...

  2. PAT-1010 Radix

    1010 Radix (25 分) Given a pair of positive integers, for example, 6 and 110, can this equation 6 = 1 ...

  3. DRF框架QQ登录功能

    用户模块---QQ登录 流程图 QQ登录文档:http://wiki.connect.qq.com/%E5%87%86%E5%A4%87%E5%B7%A5%E4%BD%9C_oauth2-0 流程简述 ...

  4. Linux内核分析——第五周学习笔记

    第五周 扒开系统调用的“三层皮”(下) 一.知识点总结 (一)给MenuOS增加time和time-asm命令 在实验楼中,首先 强制删除menu (rm menu -rf) 重新克隆一个新版本的me ...

  5. C#简述(二)

    详情请参考:http://www.runoob.com/csharp/csharp-operators.html 1.C# 运算符 算术运算符 关系运算符 逻辑运算符 位运算符 赋值运算符 其他运算符 ...

  6. iptables之四表五链

    iptables可谓是SA的看家本领,需要着重掌握.随着云计算的发展和普及,很多云厂商都提供类似安全组产品来修改机器防火墙. iptables概念 iptables只是Linux防火墙的管理工具而已. ...

  7. BZOJ2568 比特集合(树状数组)

    考虑维护f[k][x]表示“最低k位所表示的数不大于x”的数的个数.那么查询时答案就为f[k][2k-1]-f[k][2k-1-1]. 同时记录每个数在集合中出现多少次.这样的话插入.删除已经解决了, ...

  8. idea和eclipse的区别

    使用基于IntelliJ的IDE,都会对project和module的关系比较糊涂.用简单的一句话来概括是: IntelliJ系中的Project相当于Eclipse系中的workspace.Inte ...

  9. python_面向对象魔法方法指南

    原文: http://www.rafekettler.com/magicmethods.html 原作者: Rafe Kettler 翻译: hit9 原版(英文版) Repo: https://gi ...

  10. 【题解】 bzoj1911: [Apio2010]特别行动队 (动态规划+斜率优化)

    bzoj1911,懒得复制,戳我戳我 Solution: 线性DP(打牌) \(dp\)方程还是很好想的:\(dp[i]=dp[j-1]+a*(s[i]-s[j-1])^2+b*(s[i]-s[j-1 ...