以下所有纯属个人习惯,不喜勿喷
语言:应该使用美国英语命名 如
UIColor *myColor = [UIColor whiteColor];
而不是:
UIColor *myColour = [UIColor whiteColor];
注释
1、方法注释
注释必须列出 函数名称、功能描述、输入参数、返回值描述、修改信息等
备注:方法名称、功能描述要正确描述。
/**
* 方法名称
* 功能描述
*
* @param 输出参数1 输出参数描述
* @param 输出参数2 输出参数描述
*
* @return 返回值 返回值描述
*
* 其他说明:如修改信息等
*
*/
2、对单条语句注释
注释应与其描述的代码相近,对代码的注释应该放在其上方或右方相邻位置,不可放在下面,需与上一行代码隔开一行空行
/* 代码段1注释*/
[代码段1];
/* 代码段2 注释*/
[代码段2];
3、方法大括号和其他大括号(if/else/switch/while 等.)总是在同一行语句打开但在新行中关闭
应该:
if (user.isHappy) {
//Do something
} else {
//Do something else
}
不应该:
if (user.isHappy)
{
//Do something
}
else{
//Do something else
}
4、避免以对齐方式调用含有block代码块的方法
应该:
// 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
}];
命名
Apple命名规则尽可能坚持长的,描述性的方法和变量性
//应该:
UIButton *settingsButton;
//不应该:
UIButton *setBut;
备注:对于一些特殊类型的变量,命名时要带上类型,如NSArray的变量命名为xxxArray,其他的如xxxDictionary,xxxSize等。这样就可以从名称上知道是什么类型的变量。千万不能将NSArray的变量命名为xxxDictionary。
const 常量命名
常量应该使用驼峰式命名规则,所有单词首字母大写和加上与类名有关的前缀
//应该:
static NSTimeInterval const kRWTTutorialViewControllerNavigationFadeAnimationDuration = 0.3;
//不应该:
static NSTimeInterval const fadetime = 1.7;
一些常量前加特殊前缀,可以作为不同常量的区分,
如:
/**
* UserDefault Key 的常量前加 ‘kUDK’,
* NotificationName Key 的常量前加‘kNNK’,
* Dictionary Key 的常量前加‘kDICK’,
* Model Key 的常量前加 ‘kMDK’,
* Localizable Key 的常量前加 ‘kLOCK’,
* 第三方服务 Key 的常量前加 ‘kVENDK’,
* 十六进制颜色值 的常量前加 ‘kHEXCOR’,
* 图片资源名字 的常量前加 ‘kIMGN’
*/
备注:‘k’for ‘constant’ ‘K’ for ‘key’
宏定义命名
应当能够表达它的用途,并且使用大写字母表示,每个单词间用’_’分开
如果使用宏定义表示常量则前面必须加k表示理解为常量“constant“,不过建议使用const定义常量
类的命名
1.所有类名均以大写字母开头,多单词组合时,后面单词首字母大写。类接口名必须有意义
2、所有类名前面添加前缀 “RJ”
3.继承自UIView的类以View结尾。
如:RJOperatorUsersInfomationView
4.继承自ViewController的类以ViewController结尾。
如:RJHomeViewController
5.所有保存数据的实体以Model结尾。
如:RJUserModel
属性也是使用驼峰式
对于属性的实例化,我们应该尽可能使用延迟实例
@property (strong , nonatomic) UIView *descriptionView;
//应该:
- (UIView *)descriptionView {
if (!_descriptionView) {
_descriptionView = [[UIView alloc] init];
}
return _descriptionView;
}
//不应该
self.descriptionView = [[UIView alloc] init];
下划线
当使用属性时,实例变量应该使用’self.’来访问和改变。
备注:在初始化方法里,实例变量(如:_variableName)应该直接被使用来避免getters/setters潜在的副作用。
局部变量不应该包含下划线。
方法
在方法签名中,应该在方法类型(-/+ 符号)之后有一个空格。在方法各个段之间应该也有一个空格(符合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.
变量
1.变量尽量以描述性的方式来命名。单个字符的变量命名应该尽量避免,除了在for()循环。
2.星号表示变量是指针。例如, NSString *text 既不是 NSString* text 也不是 NSString * text,除了一些特殊情况下常量。
3.私有属性应该尽可能代替实例变量的使用。尽管使用实例变量是一种有效的方式,但更偏向于使用属性来保持代码一致性。
//应该:
@interface RWTTutorial : NSObject
@property (nonatomic, strong) NSString *tutorialName;
@end
//不应该:
@interface RWTTutorial : NSObject {
NSString *tutorialName;
}
属性特性
所有属性特性应该显式地列出来,有助于新手阅读代码。属性特性的顺序应该是nullable,nonatomic,readonly,strong
,与在APPLE 本身框架库代码一致。
//应该:
@property (nonatomic, weak) IBOutlet UIView *containerView;
@property (nonatomic) NSString *tutorialName;
//不应该:
@property (weak, nonatomic) IBOutlet UIView *containerView;
@property (strong, nonatomic) NSString *tutorialName;
代码组织
在函数分组和protocol/delegate实现中使用 ‘#pragma mark – ’来分类方法,要遵守以下一般的结构:
#pragma mark - Lifecycle
- (instancetype)init {}
- (void)dealloc {}
- (void)viewDidLoad {}
- (void)viewWillAppear:(BOOL)animated {}
- (void)didReceiveMemoryWarning {}
#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 {}
#pragma mark - Custom Accessors
- (void)setCustomProperty:(id)value {}
- (id)customProperty {}
黄金路径
当使用条件语句编码时,上边的代码应该是"golden" 或 "happy"路径。也就是不要嵌套if语句,多个返回语句也是OK。
//应该:
- (void)someMethod {
if (![someOther boolValue]) {
return;
}
//Do something important
}
//不应该:
- (void)someMethod {
if ([someOther boolValue]) {
//Do something important
}
}
换行符
换行符是一个很重要的主题,因为它的风格指南主要为了打印和网上的可读性。
例如:
self.productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:productIdentifiers];
//一行很长的代码应该分成两行代码,下一行用两个空格隔开。
self.productsRequest = [[SKProductsRequest alloc]
initWithProductIdentifiers:productIdentifiers];
Init方法
Init方法应该遵循Apple生成代码模板的命名规则,返回类型应该使用instancetype而不是id。
- (instancetype)init {
self = [super init];
if (self) {
// ...
}
return self;
}
类构造方法
当类构造方法被使用时,它应该返回类型是instancetype而不是id。这样确保编译器正确地推断结果类型。
@interface Airplane
+ (instancetype)airplaneWithType:(RWTAirplaneType)type;
@end
修改规范
1、新增代码行
新增代码行的前后应有注释行说明。
//修改人,修改时间,修改说明
新增代码行
//修改结束
2、删除代码行
删除代码向的前后用注释行说明
//修改人,修改时间,修改说明
要删除的代码行(将要删除的语句进行注释)
//修改结束
3、修改代码行
修改代码行以注释旧代码行后再新增代码行的方式进行。
//修改人,修改时间,修改说明
//修改前代码行开始
//修改前代码行
//修改前代码行结束
//修改后代码行开始
修改后代码行
//修改结束