iOS代码规范

作者: 江湖闹士 | 来源:发表于2021-05-29 08:51 被阅读0次

前言:无规矩不成方圆,项目开发过程中,代码规范看起来是一件不起眼的事,每个接手开发的人用按照自己的一套习惯来操作命名,随着项目壮大,整体看就会感觉很乱,没有章法,让人没有欲望去了解去接手。
一个好的命名规范:代码应该简洁、易读、易懂,逻辑清晰。
核心原则:写代码不要炫技,用简单直观符合思维惯性的方式去写代码,降低别人的理解成本。
那么我们就从iOS常用的类、方法等一一列举。

一、资源规范

图片资源

1、(组件化开发中)各组件图片资源应该放到各自组件assets中,不允许业务新增资源丢到壳工程中
2、图片资源命名单词小写以下划线拼接如:
tabbar_mine_select

二、代码规范

类的布局

为了他人阅读你代码容易,请让你写的类按照以下方式进行布局。(⚠️注意:#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(大驼峰命名)风格,必须遵从驼峰形式,专有名词除外:如:UDP。
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、方法命名举例: 属性/函数/参数/变量/常量/宏 的命名应该保持清晰+简洁,如果鱼和熊掌不能兼得,那么清晰更重要

Good:
insertObject: atIndex:  
removeObjectAtIndex:
removeObject: 

Bad:
insert:at:  不清晰,插入什么?at代表什么?
remove: 不清楚到底要删什么?

Good:
- (NSSize)cellSize;
- (int)runModalForDirectory:(NSString *)path file:(NSString *) name types:(NSArray *)fileTypes;
- (void)sendAction:(SEL)aSelector toObject:(id)anObject forAllCells:(BOOL)flag;

Bad:
- (NSSize)getCellSize;
- (int)runModalForDirectory:(NSString *)path andFile:(NSString *)name andTypes:(NSArray *)fileTypes;
- (int)runModalForDirectory:(NSString *)path withFile:(NSString *)name withTypes:(NSArray *)fileTypes;
- (void)sendAction:(SEL)aSelector :(id)anObject :(BOOL)flag;

1、类的命名以公司特定标识开头,比如科瑞有限公司,那么就 KR 开头(下面都用KR做例子)。
2、类名:类名的命名遵循大驼峰式命名法,类名中可以添加工程的前缀,防止多个子工程出现类名重复的情况。
3、如果是 Model必须使用 Model 结尾,View 必须是 View结尾,UIViewController VC 结尾,UITableViewController TVC结尾,UICollectionViewController CVC 结尾。
4、MVVM 中的 ViewModel以Logic 结尾,里面只能放逻辑,不能有任何 UI相关的代码。LogicViewController的数据传递推荐使用代理BlockObserver不可以使用通知。
5、不要在工具类里面写业务逻辑,工具类就是工具类。
6、在类的头文件中尽量少引用其他头文件,使用 @class 声明。
7、创建一个类的时候,里面默认生成的被苹果注释掉的代码,全部删掉。包括-(void)didReceiveMemoryWarning也要删除,平时注掉不用的代码如无特殊原因,一概删除,注掉不删,要写明不能删的原因。
8、Router协议命名:KR+名称+RouterProtocol KRMineRouterProtocol
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、在方法之间应该有且只有一行。这样有利于在视觉上更清晰。方法内为了视觉清晰,也酌情空行,但不要每写一行就空一行,够一个功能段空一行

分类

分类命名要用 " KR"开头,如:UIColor+KRExtensions.h,暴露出来的方法要以 "kr_"开头,如:

@interface UIColor (KRExtensions)
- (UIColor *)kr_customColor;
@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 KRTopicController () <UITableViewDelegate, UITableViewDataSource, KRTopicHeaderViewDelegate>
@end

@implementation KRTopicController
@end

2、不允许这样写 self.tableView.delegate = (id)self;
这样写的坏处是:当看一个类里面的方法,发现没有地方调用,但这个方法也会走,怀疑是个代理,但看看头文件又没实现这个代理,看代码的人是很恐慌的。
3、代理一般情况下都是有两个或两个以上参数的,第一个参数返回调用代理的owner,如:

@class KRTopicHeaderView;
@protocol KRTopicHeaderViewDelegate <NSObject>
@optional
- (void) topicHeaderView:(KRTopicHeaderView *)view tapAvatar:(UIButton *)avatarBtn;
- (void) topicHeaderView:(KRTopicHeaderView *)view tapCreditScore:(UIButton *)creditScoreBtn;
@end

变量

1、变量名的命名规范遵循小驼峰式命名法(方法参数名的命名规则和变量名一致)。
2、一个变量有且只有一个功能,尽量不要把一个变量用作多种用途
3、一行声明一个变量,不要一行声明多个变量
4、少用变量标记,多用方法传值。
5、强烈建议使用枚举来定义一些变量。
6、不要使用 floatint 定义基本类型,使用 CGFloatNSInteger
代替,这样的好处是 32 位的机型 CGFloat 会转为 float,64 位的机型 CGFloat
会转为double

属性

1、变量定义,推荐用属性的方式去声明,不要用全局变量
全局变量的声明方式是MRC时代的编码风格,现在是ARC时代,不要用。要注意,属性的声明

@interface KRTopicController { 
    _varxxx; 
}
// *应该紧挨着变量名。
@interface KRTopicController () 
@property (nonatomic, strong) KRTopicHeaderView *headerView;
@property (nonatomic, strong) KRTopicFooterView *footerView;
@end

@implementation KRTopicController
@end

2、public 属性放 .h 文件里面,private 属性放 .m
文件的匿名分类里面。不要用 _xxx 的写法。
3、尽量使用不可变对象。包括:
(1)在头文件中,设置对象属性为readonly
(2)NSStringNSDictionaryNSArray 使用 copy关键字指定
(3)字典 使用 NSDictionary,而不是 NSMutableDictionary;数组 使用
NSArray,而不是 NSMutableArray
(4)向集合类型中添加元素要添加非空判断。

常量

常量定义,如果是给整个项目使用的常量定义为:
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、宏定义不允许定义字符串、字面值只能用来定义代码段。

枚举

枚举定义应该使用 OC的声明方式,避免使用C的写法。定义方式如下:
typedef NS_ENUM(NSInteger, KRInformationType) {
    KRInformationLikeType = 0,// 喜欢
    KRCommentType ,// 评论
    KRMentionType ,// @
    KRSysMsgType // 系统消息
};

Block

1、调用block时需要对block判空
2、block中如果使用了self,block用 @weakify(self); Block 中使用
@strongify(self);不要自己写 weakstrong

通知

除特殊情况下,不允许使用。

引入第三方代码

引入第三方代码要注意,必须是在社区有一定知名度,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赋值正确写法:

Good:
BOOL isAdult = age > 18;

Bad:
BOOL isAdult;
if (age > 18) {
    isAdult = YES;
  } else {
    isAdult = NO;
}

4、工程名:工程名的命名必须有强烈的导向性,让人看到工程名的第一眼就明白该工程对应哪个项目。如KRUserModule
工程名字不能出现中文,不允许有空格。 工程名字采用大驼峰式命名法。

相关文章

  • iOS 代码规范篇

    iOS 代码规范篇 iOS 代码规范篇

  • iOS Coding Style Guide 代码规范

    iOS Coding Style Guide 代码规范 iOS Coding Style Guide 代码规范

  • 乐乎-代码规范概述

    参考: 1、iOS中书写代码规范35条小建议 2、iOS开发总结之代码规范 3、iOS代码编程规范-根据项目经验汇...

  • iOS 代码规范文档

    iOS 代码规范文档 [toc] 修订 概述 制定目的:制定iOS 编码规范,主要是为了规范公司内部的iOS 代码...

  • iOS -如何让你写的代码更规范

    iOS -如何让你写的代码更规范 iOS -如何让你写的代码更规范

  • 代码之天圆地方

    优雅的写代码轻松的查代码严格的审代码 一、 iOS代码规范检查 新人入场第一件事就是熟悉代码规范iOS代码编程规范...

  • iOS开发总结之代码规范

    iOS开发总结之代码规范

  • iOS知识整理(二)

    OC知识整理 代码规范 iOS 代码规范 #pragma mark - 添加子视图#pragma mark - 添...

  • iOS 代码规范

    iOS规范:仅适用于iOS的代码规范(使用Objective-C语言)。 一.代码应该简洁易懂,逻辑清晰 不要过分...

  • iOS 团队编程规范

    iOS 团队编程规范 前 言 一、命名规范 二、代码注释规范 三、代码格式化规范 四、编码规范 参考资料: 转载自...

网友评论

    本文标题:iOS代码规范

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