美文网首页
iOS Coding Guidelines(代码指南)

iOS Coding Guidelines(代码指南)

作者: 肥猫不喵 | 来源:发表于2019-06-04 19:49 被阅读0次
版本号 编写人 日期
1.0 Jeremy 2019-05-29

一、命名基础

驼峰命名

  • 针对属性、变量、方法等均采用小写字母开头的驼峰命名准则。
  • 针对类、枚举、宏等均采用大写字母开头的驼峰命名准则。

清晰性

  • 最好是既清晰又简短,但不要为简短而丧失清晰性

  • 示例:removeObject:

  • 反例:remove

  • 名称通常不缩写,即使名称很长,也要拼写完全

  • 示例:destinationSelection

  • 反例:destSel

我们尽可能遵守 Apple 的命名约定,其推荐使用长的、描述性强的方法和变量名,使其阅读起来更加清晰易懂。不可随意使用缩写,导致他人阅读代码困难。

一致性

  • 尽可能使用与 Cocoa 编程接口命名保持一致的名称。如果你不太确定某个命名的一致性,请浏览一下头文件。
  • 在使用多态方法的类中,命名的一致性非常重要。在不同类中实现相同功能的方法应该具有相同的名称
  • 示例:- (NSInteger)tag
  • 示例:- (void)setStringValue:(NSString *)

前缀

前缀是名称的重要组成部分,它们可以区分应用的功能范畴。前缀可以防止与第三方开发者之间的命名冲突

  • 前缀有规定的格式。它由两到三个大写字符组成,不能使用下划线与子前缀
  • 命名 class, protocol, structure, 函数,常量时使用前缀;命名成员方法时不使用前缀,因为方法已经在它所在类的命名空间中;同理,命名结构体字段时也不使用前缀

二、方法命名

一般性规则

为方法命名时,请考虑如下一些一般性规则:

  • 小写第一个单词的首字符,大写随后单词的首字符,不使用前缀。有两种例外情况:
  1. 方法名以广为人知的大写字母缩略词(如 TIFF or PDF)开头
  2. 私有方法可以使用统一的前缀来分组和辨识
  • 表示对象行为的方法,名称以动词开头

  • 示例:- (void)invokeWithTarget:(id)target:

  • 示例:- (void)selectTabViewItem:(NSTableViewItem *)tableViewItem

  • 如果方法返回方法接收者的某个属性,直接用属性名称命名。不要使用 get,除非是间接返回一个或 多个值。

  • 示例:- (NSSize)cellSize

  • 反例:- (NSSize)getCellSize

  • 不要使用 and 来连接用属性作参数关键字

  • 示例:- (int)runModalForDirectory:(NSString *)path file:(NSString *)name

  • 反例:- (int)runModalForDirectory:(NSString *)path addFile:(NSString *)name

方法参数

命名方法参数时要考虑如下规则:

  • 如同方法名,参数名小写第一个单词的首字符,大写后继单词的首字符。

  • 示例:removeObject:(id)anObject

  • 不要在参数名中使用 pointer 或 ptr,让参数的类型来说明它是指针

  • 避免使用 one, two,…,作为参数名

  • 避免为节省几个字符而缩写

按照 Cocoa 惯例,以下关键字与参数联合使用:

...action:(SEL)aSelector
...alignment:(int)mode
...atIndex:(int)index
...content:(NSRect)aRect
...doubleValue:(double)aDouble
...floatValue:(float)aFloat
...font:(NSFont *)fontObj
...frame:(NSRect)frameRect
...intValue:(int)anInt
...keyEquivalent:(NSString *)charCode
...length:(int)numBytes
...point:(NSPoint)aPoint
...stringValue:(NSString *)aString
...tag:(int)anInt
...target:(id)anObject
...title:(NSString *)aString

三、实例变量与数据类型命名

实例变量

在为类添加实例变量是要注意:

  • 避免创建 public 实例变量
  • 确保实例变量名简明扼要地述了它所代表的属性
  • 使用 property 代替 public 实例变量,格式如下
  • 示例:@property (nonatomic, copy) NSString *name;

如果实例变量别设计为可被访问的,确保编写了访问方法并注意读写权限。

枚举常量

  • 使用枚举来定义一组相关的整数常量
typedef NS_ENUM(NSInteger, NSMatrixMode) { 
    NSRadioModeMatrix = 0, 
    NSHighlightModeMatrix = 1,
    NSListModeMatrix = 2, 
    NSTrackModeMatrix = 3
};

其他常量

  • 通常不使用 #define 来创建常量。如上面所述,整数常量请使用枚举。
  • 使用大写字母来定义预处理编译宏。如:#ifdef DEBUG
  • 为 notification 名及 dictionary key 定义大驼峰字符串常量,从而能够利用编译器的拼写检查,减少书写错误。

四、可接受的缩略语

在设计编程接口时,通常名称不要缩写。下面列出的缩写要么是固定下来的要么是过去被广泛使用的,所以可以继续使用。关于缩写有一些额外的注意事项:

  • 标准 C 库中长期使用的缩写形式是可以接受的。如:”alloc”, “getc”
  • 你可以在参数名中更自由地使用缩写。如: imageRep, col(column), obj, otherWin

常见的缩写

缩写 含义 缩写 含义
alloc Allocate alt Alternate
app Application calc Alternate
dealloc dealloc func Function
horiz Horizontal info Information
init Initialize int Integer
max Maximum min Minimum
msg Message nib Interface Builder archive
pboard Pasteboard rect Rectangle
Rep Representation temp Temporary
vert Vertical

补充的缩写

缩写 含义 缩写 含义
idx Index btn Button
proj Project pro Professional
pwd Password pic Picture
str String img Image

五、编码格式

星号(*)位置

  • 定义一个对象时,*靠近变量

  • 示例:NSString *userName;

统一的ViewController模板(代码缩进、Method进行分组、大括号写法)

  • import引用分组划分
  • 使用property与局部变量,不使用用全局变量(不能显性区分作用域)
  • 空格与换行建议(参照iOS SDK API)
  • 方法功能区域性划分
#import "GMBaseViewController.h"
///首页HomePage
@interface GMHomePageViewController : GMBaseViewController
///项目Id
@property (nonatomic, copy) NSString *projectId;
@end
#import "GMHomePageViewController.h"
#import "GMHomePageTableViewCell"   //View
#import "GMHomePageListRequest"     //Model数据类
#import "GMProjectViewController"   //非本页面所用

@interface GMHPViewController ()

@end

@implementation GMHPViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self setupView];
    [self loadData];
}

- (void)setupView {

}

- (void)loadData {
   
}

#pragma mark - UITableViewDataSource && UITableViewDelegate

#pragma mark - Custom Methods

#pragma mark - Event Response

#pragma mark - Getter && Setter

条件语句

  • 条件判断语句执行主体不管是 if 里面还是 else 里面都必须要使用大括号包住, 即使代码是一行的情况。for 循环同样。
  • if-else中,else不另起一行,与if的反括号在同一行,如下段代码所示,注意else前后均有空格。
  • switch-case中,建议所有case和default后的代码块均用{}包裹。
if(success){
    ...
} else {
    ...
}

for(int i = 0 ; i < 10 ; i++){
    ...
}

单一原则

  • 每个函数的职责都应该划分明确(如类一样)

模型解析(MJExtension)

+ (NSDictionary *)mj_replacedKeyFromPropertyName {
    return @{@"uid" : @"id"};
}

+ (NSDictionary *)mj_objectClassInArray {
    return @{@“block” : @"GMBlockModel"};
}

其他

  • NSUserDefaults使用时,Key需加入本功能相应前缀并全局搜索本项目避免重复,防止互相影响
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setBool:YES forKey:[NSString stringWithFormat:@"GMGuideVersion_%@", version]];
  • 子类重写父类方法一般需先调用父类方法
- (void)viewDidLoad {
    [super viewDidLoad];
    ...
}
  • 单模块多页面可新建模块Header类,统一导入共用类,设定常量等。非全局不可定义在PCH

六、代码注释

优秀的代码大部分是可以自描述的,我们完全可以用代码本身来表达它到底在干什么,而不需要注释的辅助。
但并不是说一定不需要写注释,有以下三种情况需要编写注释:

  • 公共接口(注释要告诉阅读代码的人,当前类能实现什么功能,譬如:基础类、工具类)
  • 涉及到比较深层专业知识及业务逻辑的代码(注释要体现出实现原理和思想)
  • 容易产生歧义的代码(但是严格来说,容易让人产生歧义的代码是不允许存在的)

import注释

如果有一个以上的import语句,就对这些语句进行分组,每个分组的注释是可选的。

属性注释

///注释 
@property (nonatomic, strong) UIView *headerView;

方法声明注释

公开接口,重要的方法,分类,以及协议都应该伴随注释。方法的注释使用Xcode自带注释快捷键:Commond+option+/或者///,这两种注释方式可被XcodeQuick Help识别

/**
 <#Description#>

 @param tableView <#tableView description#>
 @param section <#section description#>
 @return <#return value description#>
 */
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
   ...
}

///<#Description#>
- (void)getUserInfo {
    ...
}

参考文档:Apple Coding Guidelines for Cocoa

相关文章

网友评论

      本文标题:iOS Coding Guidelines(代码指南)

      本文链接:https://www.haomeiwen.com/subject/tfgrxctx.html