一、资源规约
1、图片资源
二、代码规约
1、类的布局
2、类
3、方法
4、分类
5、单利
6、代理
7、变量
8、属性
9、常量
10、宏定义
11、枚举
12、Block
13、通知
14、引入第三方代码
15、注释
16、其他
代码应该简洁、易读、易懂,逻辑清晰。
核心原则:写代码不要炫技,用简单直观符合思维惯性的方式去写代码,降低别人的理解成本。
一、资源规约
1、(一) 图片资源
- 各组件图片资源应该放到各自组件assets中,不允许业务新增资源再丢到壳工程中
- 图片资源命名单词小写以下划线拼接如:nearby_bike_image
二、代码规约
类的布局
为了团队其他成员阅读你代码容易,请让你写的类按照以下方式进行布局。(⚠️注意:#pragma mark 后面有个" - ")
#pragma mark - Life Cycle
#pragma mark - Setup View / Data
#pragma mark - Observer
#pragma mark - Notification
#pragma mark - Event Response
#pragma mark - Override Methods
#pragma mark - Delegate
#pragma mark - Public Methods
#pragma mark - Private Methods
#pragma mark - Setter / Getter
#pragma mark - Network
二、命名
1、代码中的命名严禁使用拼音与英文混合的方式,更不允许直接使用中文的方式。
2、类名使用 UpperCamelCase(大驼峰命名)
风格,必须遵从驼峰形式,专有名词除外:如:TCP。
3、方法名、参数名、成员变量、局部变量都统一使用 lowerCamelCase
(小驼峰命名)风格,必须遵从驼峰形式。
4、一个标识符的命名应该简单好懂,避免使用复杂单词。
5、viewDidLoad 和 init 方法里面不能把初始化 UI 和
数据的代码混在一起,要拆成两个方法。初始化 UI 和 数据的方法放在 #pragma
mark - Setup View / Data 里面,而且方法的命名应该避免使用 init、get、set
开头,建议命名:
- (void)setupViews;
- (void)setupUI;
- (void)createUI;
- (void)configData;
- (void)setupData;
- (void)fetchData;
6、当一个页面要刷新 UI 或者数据时,建议的命名是:
- (void)updateUI;
- (void)refreshUI;
- (void)reloadData;
- (void)refreshData;
7、方法命名举例: 属性/函数/参数/变量/常量/宏
的命名应该保持清晰+简洁,如果鱼和熊掌不能兼得,那么清晰更重要
insertObject: atIndex: Good.
insert:at: 不清晰,插入什么?at代表什么?
removeObjectAtIndex: Good.
removeObject: Good, because it removes object referred to in argument.
remove: Not clear; what is being removed?
- (NSSize)cellSize; Right.
- (NSSize)getCellSize; Wrong.
- (int)runModalForDirectory:(NSString *)path file:(NSString *) name types:(NSArray *)fileTypes; Right.
- (int)runModalForDirectory:(NSString *)path andFile:(NSString *)name andTypes:(NSArray *)fileTypes; Wrong.
- (int)runModalForDirectory:(NSString *)path withFile:(NSString *)name withTypes:(NSArray *)fileTypes; Wrong.
- (void)sendAction:(SEL)aSelector toObject:(id)anObject forAllCells:(BOOL)flag; Right.
- (void)sendAction:(SEL)aSelector :(id)anObject :(BOOL)flag; Wrong.
类
1、类的命名必须是 JY 开头,代表的 "静遥网络"
的意思,HelloBike 项目立项的时候大家都还在静遥网络下面的 "车钥匙"(CK)项目做事。项目还没有确定项目名,当时是以 "EasyBike"开始开发的,所以项目名叫EasyBike。
2、类名:类名的命名遵循大驼峰式命名法,类名中可以添加工程的前缀,防止多个子工程出现类名重复的情况。
3、如果是 Model,必须使用 Model 结尾,View 必须是 View结尾,UIViewController VC 结尾,UITableViewController TVC结尾,UICollectionViewController CVC 结尾。
4、MVVM 中的ViewModel
以Logic
结尾,里面只能放逻辑,不能有任何 UI相关的代码。Logic
和ViewController
的数据传递推荐使用代理、Block、Observer,不可以
使用通知。
5、不要在工具类里面写业务逻辑,工具类就是工具类。
6、在类的头文件中尽量少引用其他头文件,使用 @class 声明。
7、创建一个类的时候,里面默认生成的被苹果注释掉的代码,全部删掉。包括 -(void)didReceiveMemoryWarning也要删除,平时注掉不用的代码如无特殊原因,一概删除,注掉不删,要写明不能删的原因。
8、Router协议命名:JY+名称+RouterProtocol (JYHomeRouterProtocol)
9、【推荐】如果你重写了初始化方法,希望用调用方用你写的构造函数,那么请用:NS_DESIGNED_INITIALIZER
宏来指定调用方使用哪个初始化方法。如:
- (instancetype)initWithText:(NSString *)text NS_DESIGNATED_INITIALIZER;
10、【推荐】如果你想让调用方只使用你写构造函数,也可以用 NS_UNAVAILABLE
屏蔽系统的构造函数。如:
+ (instancetype)new NS_UNAVAILABLE;
- (instancetype)init NS_UNAVAILABLE;
- (instancetype)initWithCoder:(NSCoder *)aDecoder NS_UNAVAILABLE;
- (instancetype)initWithFrame:(CGRect)frame NS_UNAVAILABLE;
11、【推荐】如果你提供的方法想弃用掉,发现调用的地方比较多,一下子全改风险大,请用
attribute((deprecated("已弃用, 用payWithPayInfo替换")));标明弃用,随着版本迭代逐步替换使用新方法。
方法
1、方法名的命名规范遵循小驼峰式命名法
2、要 区分方法调用和属性访问
推荐:
view.backgroundColor = [UIColor orangeColor];
[UIApplication sharedApplication].delegate;
不推荐:
[view setBackgroundColor:[UIColor orangeColor]];
UIApplication.sharedApplication.delegate;
3、方法后面的花括号不能换行。
4、单一职责原则,一个方法只干一件事情。
5、重载方法的时候,如无特殊情况均需要先调用super的方法。
6、在方法之间应该有且只有一行。这样有利于在视觉上更清晰。方法内为了视觉清晰,也酌情空行,但不要每写一行就空一行,够一个功能段空一行
分类
1、分类命名要用 " JY"开头,如:NSTimer+JYExtensions.h,暴露出来的方法要以 "jy_"开头,如:
@interface NSDate (JYExtensions)
- (NSString *)jy_stringFromDate;
@end
单例
1、使用 dispatch_once 来生成单例
2、单例方法命名都应该加上 shared
如: + (instancetype)defaultManager;
不知道该怎么给单例方法起名字就用:+ (instancetype)sharedInstance;
3、【建议】如果声明了单例请用 NS_UNAVAILABLE 屏蔽掉 init 方法,如:
- (instancetype)init NS_UNAVAILABLE;
+ (instancetype)new NS_UNAVAILABLE;
代理
1、一个类实现了那些代理,要明确的写到.m文件匿名分类的后面。苹果官方的写在前面,自定义的写在后面如:
@interface JYLeftMenuController () <UITableViewDelegate, UITableViewDataSource, JYLeftMenuHeaderViewDelegate>
@end
@implementation JYLeftMenuController
@end
2、不允许这样写 self.tableView.delegate = (id)self;
这样写的坏处是:当看一个类里面的方法,发现没有地方调用,但这个方法也会走,怀疑是个代理,但看看头文件又没实现这个代理,看代码的人是很恐慌的。
3、代理一般情况下都是有两个或两个以上参数的,第一个参数返回调用代理的owner,如:
@class JYLeftMenuHeaderView;
@protocol JYLeftMenuHeaderViewDelegate <NSObject>
@optional
- (void)leftMenuHeaderView:(JYLeftMenuHeaderView *)view tapAvatar:(UIButton *)avatarBtn;
- (void)leftMenuHeaderView:(JYLeftMenuHeaderView *)view tapCreditScore:(UIButton *)creditScoreBtn;
@end
变量
1、变量名的命名规范遵循小驼峰式命名法(方法参数名的命名规则和变量名一致)。
2、一个变量有且只有一个功能,尽量不要把一个变量用作多种用途
3、一行声明一个变量,不要一行声明多个变量
4、少用变量标记,多用方法传值。
5、不要使用魔数,使用枚举来定义,碰到使用魔数的代码一定会打回。
6、不要使用 float、int 定义基本类型,使用 CGFloat 和 NSInteger
代替,这样的好处是 32 位的机型 CGFloat 会转为 float,64 位的机型 CGFloat
会转为 double
属性
1、变量定义,推荐用属性的方式去声明,不要用全局变量
@interface JYLeftMenuController {
_varxxx;
}
全局变量的声明方式是MRC时代的编码风格,现在是ARC时代,不要用。要注意,属性的声明
- 应该紧挨着变量名。
@interface JYLeftMenuController ()
@property (nonatomic, strong) JYLeftMenuHeaderView *headerView;
@property (nonatomic, strong) JYLeftMenuFooterView *footerView;
@end
@implementation JYLeftMenuController
@end
2、public 属性放 .h 文件里面,private 属性放 .m
文件的匿名分类里面。不要用 _xxx 的写法。
3、尽量使用不可变对象。包括:
(1)在头文件中,设置对象属性为readonly。
(2)NSString、NSDictionary、NSArray 使用 copy 关键字指定
(3)字典 使用 NSDictionary,而不是 NSMutableDictionary;数组 使用
NSArray,而不是 NSMutableArray。
(4)向集合类型中添加元素要添加非空判断。
常量
1、常量定义,如果是给整个项目使用的常量定义为:
static NSString *const kSimpleString = @"simpleString";
如果只是给某个类使用的常量,定义为: static NSString *const
kClassNameConstName = @"ClassNameConstName";,
宏定义和常量在 Xcode
里面的显示颜色是不一样的,足以区分。当一个标识符既可以用宏定义又可以用常量的情况下首选常量。原因:常量可以在控制台打印方便调试。
宏定义
1、宏定义
#define kSafeStr(str) (([str isKindOfClass:[NSNull class]] || !str) ? @"" : [NSString stringWithFormat:@"%@", str])
小写k开头然后遵循小驼峰命名法。
2、宏定义不允许定义字符串、字面值只能用来定义代码段。
枚举
1、枚举定义应该使用 OC的声明方式,避免使用C的写法。定义方式如下:
typedef NS_ENUM(NSInteger, JYInformationType) {
JYInformationLikeType = 0,// 喜欢
JYCommentType ,// 评论
JYMentionType ,// @
JYSysMsgType // 系统消息
};
Block
1、调用block时需要对block判空
2、Block中如果使用了self,Block用 @weakify(self); Block 中使用
@strongify(self);不要自己写 weak、strong。
通知
除特殊情况下,不允许使用。
引入第三方代码
引入第三方代码要注意,必须是在社区有一定知名度,github star数要够多,同一个功能的库找最多的用,必须用pod管理。有一种情况是你要做的功能就是没有知名库,但有别人已经写好的,是可以引用的,但review时会问你原因,review的人要根据他说的情况搜一下,看是不是真的没有知名库可以用。
注释
1、注释的作用:一份规范的代码必定不能缺少详尽的注释,注释的目的:方便工作交接和引导新同事熟悉代码 方便自己之后回忆代码逻辑 方便生成文档
2、注释分为单行注释和多行注释 (1)对于属性我们使用三杠 /// 进行单行注释,这样 Xcode 代码提示的时候会显示注释内容
///用户名
@property (nonatomic, copy) NSString *userName;
(2)对于特殊行//代码块注释的注释的使用双杠 //
if(orderType == JYOrderTypeNone){
//无订单处理
}
(3)对于方法我们使用多行注释
/**
* @brief 设置是否处于选中状态
* @param selected 是否选中
* @param animated 是否使用动画效果
*/
- (void)setSelected:(BOOL)selected animated:(BOOL)animated;
其他
1、管理缓存使用 NSCache 而不是NSMutableDictionary,好处有一下几点:
(1)NSCache 是线程安全的,在进行多线程操作时,不需要进行加锁。
(2)NSCache在系统内存很低时会自动释放对象。
2、判断nil 或者 YES/NO
正确写法:
if (someObject){ ... }
if (!someObject) { ... }
错误写法:
if (someObject == YES) { ...}
if (someObject != nil) { ...}
if (someObject == YES)容易误写成赋值语句if (someObject = YES)这样在开发的过程中不好被发现。
3、BOOL赋值正确写法: BOOL isAdult = age > 18; 错误写法:
BOOL isAdult;
if (age > 18) {
isAdult = YES;
} else {
isAdult = NO;
}
4、工程名:工程名的命名必须有强烈的导向性,让人看到工程名的第一眼就明白该工程对应哪个项目。如JYBikeModule。
工程名字不能出现中文,不允许有空格。 工程名字采用大驼峰式命名法。
网友评论