美文网首页Tools
iOS - 编码规范

iOS - 编码规范

作者: Simple_Code | 来源:发表于2020-08-19 11:35 被阅读0次

    1.⼯程⽬录说明

    1.1. Common放公共代码,Pages放业务模块相关
    image.png
    1.2. Manager全局管理类,每个管理类⼀个⽂件夹
    1.3. Api放所有的请求接⼜及返回的数据模型,每个接⼜⼀个⽂件夹,如下:
    image.png
    1.4. Base放置基础组件

    ⽬前有CassBaseView,CassBaseVC…

    1.5. Category放置分类名

    需要全局引⼊的,加⼊CassCategories.h,如下:


    image.png
    image.png
    1.6. Macro放置全局的宏(全部宏以CS_开头,必须全⼤写)
    image.png

    CassMacro⾥import所有公共宏⽂件
    CassColor公共颜⾊宏⽂件
    CassConstants公共常量宏⽂件
    CassThirdPart第三⽅平台的key,id等等
    CassCacheKey,本地缓存key
    CassNotification 通知name

    1.7. Util⼯具类
    1.8. Library ⼿动导⼊的第三⽅
    image.png
    1.9. 公⽤模块
    image.png

    注意:需要全局引⼊的,请在模块下的.h⾥引⼊,严禁放pch⾥

    2.代码格式化

    2.1.空格和空⾏的使⽤
    2.1.1.运算符的两侧使⽤空格

    所有的双⽬运算符,包括:加(+)、减(-)、乘(*)、除(/)、取余(%)、赋值
    (=、+=、-=等)、⽐较运算符(>、<、==、!=等)、逻辑运算(&&、||)、
    位运算符 (|、&、<<、>>)等的两侧都应该添加空格,⽰例如下:


    image.png

    ?:运算符在?和:的两侧都应该添加空格,⽰例如下:


    image.png

    单⽬运算符(!、++、--)⽆需添加空格:


    image.png
    2.1.2.⽅法命中空格使⽤

    ⽅法名中“+”或“-”与⽅法返回类型之间应添加⼀个空格,⽅法中参数
    类型和“*”之间应该添加
    ⼀个空格。多个⽅法的实现之间应该空⼀⾏。


    image.png

    ⽅法定义时,左⼤括号可以和⽅法名在同⼀⾏,也可以单独占⽤⼀
    ⾏,和⽅法在同⼀⾏中时,左⼤括与⽅法的最后⼀个参数之间应该空
    ⼀格:


    image.png

    ⽅法连续调⽤时,在中括号后添加空格。


    image.png
    2.1.3.属性定义时空格的使⽤

    属性定义时,property关键字与左括号,右括号与属性类型,括号中
    逗号之后,属性类型与 *之间都应该添加空格,⽰例如下:


    image.png

    属性定义时,⼩括号中各个部分的顺序约定如下:原⼦访问类型、读写权限、内存管理⽅式。


    image.png
    2.2.⾏数和列数的限制(不强制)
    2.2.1.⼀个函数的长度不应该超过80⾏

    当函数长度超过80⾏后,应该将内部⼀些复杂的逻辑提炼出来,形成
    新的函数,然后调⽤ 之,微型重构⼯作也应该⽆处不在,⽽不是等
    项⽬完成后再来重构。

    2.2.2.每⾏代码长度建议不超过120

    建议每⼀⾏代码的长度超过120字符时做折⾏处理,处理时请以结构
    清晰为原则。通过 “Xcode => Preferences => TextEditing => 勾选Show
    Page Guide / 输⼊100 => OK” 来设置提 醒

    2.2.3.每个类原则上不超过600⾏

    ⼀个类不应该将很多复杂的逻辑揉合到⼀起来实现, 我们约定当.m
    ⽂件超过600⾏时,要考 虑将这个⽂件进⾏拆分,可以使⽤类⽬
    (Category)的⽅法来分离功能代码。如果逻辑过于 复杂,则应该考虑
    从设计上将⼀些内部可以独⽴的逻辑提炼出来,形成新的类,以减轻
    单⼀ 类的复杂度。

    2.3.⽅法的声明、定义和调⽤
    2.3.1.⽅法的声明和定义

    正常情况下,所有参数应在同⼀⾏中,当参数过长时,每个参数占⽤⼀⾏,以冒号对齐。如下:


    image.png

    如果⽅法名⽐参数名短,每个参数占⽤⼀⾏,⾄少缩进4个字符,且为垂
    直对齐(⽽⾮使⽤冒号 对 齐)。如:


    image.png
    2.3.2.⽅法的调⽤

    ⽅法调⽤和⽅法声明规则⼀致,如下:


    image.png
    2.4.代码分段的使⽤

    `由于Objective-C的源码⽂件通常会⽐较⼤,代码⾏较多,推荐使⽤#pragma mark XXX 将代 码不同的处理段分隔开,分段名称的⾸母⼤写,⽅便在编辑器中快速定位到需要查看的代 码。以下是⼀些建议:

    2.4.1.Lifecycle分段

    在UIViewController的⼦类实现⽂件中,建议添加⼀个#pragma mark -
    life cycle分段,该分段包含,init、loadView、viewDidLoad、
    viewWillAppear、viewDidAppear、 viewWillDisappear、
    viewDidDisappear、viewWillLayoutSubviews、dealloc等⽅法,并建议
    将dealloc⽅法放到实现⽂件最前⾯。
    建议将Lifecycle分段放到.m⽂件的最前端,因为对⼀个类的阅读,往
    往是从init、 viewDidLoad等⽅法开始的。⽰例:


    image.png
    2.4.2.代理分段

    建议为每⼀个代理添加⼀个分段,并且分段的名称应该是代理名称,
    代理名称务必正确拼 写,这样可以通过command+单击来查看代理的
    定义,⽰例:


    image.png
    2.4.3.Property分段

    每个类都会有属性,需要为属性添加⼀个分段,该分段包括属性的
    get和set⽅法,属性⽅法 的初始化应尽量放到get⽅法中完成,⽽不应
    该全部放到viewDidLoad或者UIView的init⽅法 中,这样会增加
    viewDidLoad和init⽅法的复杂影响可读性。
    另外建议将propery分段放置在.m⽂件的最后,因为该分段主要只包
    含⼀些属性的初始⽅法 不需要太多查看,需要查看时可以直接
    command+单击跳转到get⽅法查看。


    image.png
    2.4.4.Inherit分段

    对从⽗类继承的⽅法,单独添加⼀个inherit分类,⽰例如下:


    image.png
    2.4.5.Events分段

    为button的点击事件,geture的响应⽅法,KVO的回调,Notification的
    回调⽅法添加⼀个 events分段,在该分段的⽅法中,调⽤对应业务的
    ⽅法,对应业务的⽅法放在对应业务的分 段。


    image.png
    2.4.6.Public分段

    public段的⽅法,为需要暴露给其他类,供其他类调⽤的⽅法,根据
    具体情况决定是否添加该分段。


    image.png
    2.4.7.Private分段

    private段的⽅法,是为实现本类业务⽽添加的⽅法,不需要暴露接又
    给其他类,只提供给本 类的⽅法调⽤。根据具体情况决定是否需要
    添加该分段。


    image.png
    2.4.8.根据具体业务添加分段

    在⼀个类中,为相对⽐较独⽴的业务,或者是实现相对独⽴功能的⽅
    法进⾏分段,同⼀个类 中业务不宜过多,业务过多时就应该考虑分
    拆该类了。⽰例:


    image.png
    2.4.9.分段建议

    关于分段,往往会出现的问题是,⼀个⽅法既应该放在Private段,又
    应该放在某个功能 或业务段,这种建议的处理⽅式如下:
    如果⼀类中,所有的⽅法都可以很好的归到不同的功能、业务分段,则⽆需添加
    Private段,将对应的⽅ 法放到各个业务段即可。
    如果⼀个类⽐较简单就只有⼏个⽅法,则可以将对应⽅法全部放到Private分段,⽽
    ⽆ 需添加业务分段。
    ⼀个⽅法既能放在Public段,又属于某⼀个业务段时,可以采⽤如下
    ⽅法:
    将⽅法归到其对应的业务段中,然后在Public业务段中重新定义⼀个⽅法,在该⽅
    法中调⽤业务段中对应 业务功能的实现。
    在UIViewController的实现⽂件中建议的分段及顺序如下图(根据情况
    选择需要哪些分段, 不需要总是包含以下所有分段):

    #pragma mark - Lifecycle
    #pragma mark - Inherit(继承)
    #pragma mark - Events
    #pragma mark - Delegate //各个代码分类
    #pragma mark - Public methods
    #pragma mark - Private methods
    #pragma mark - xxx //各个独立业务和独立功能的分段
    #pragma mark - Properties
    #pragma mark - 懒加载
    

    3.命名规范

    objective-c中所有命名,应以能够清晰表达其含义为第⼀标准,命名
    长⼀点没关系,最主要
    的就是清晰。
    所有命名尽量使⽤英⽂,万不得已可以使⽤拼⾳。使⽤拼⾳时,类、
    协议可以⽤拼⾳⾸字母
    做前缀,如:TM;特卖,资源图⽚,变量等使⽤拼⾳时应⽤全拼,并写
    上对应的注释。

    3.1.变量属性命名

    变量名应使⽤容易意会的应⽤全称,且⾸字母⼩写,且使⽤⾸字母⼤
    写的形式分割单词。成 员变量使⽤“_”做为前缀,以便和临时变量与
    属性区分,⽰例:


    image.png

    变量名称应直接体现出变量的类型,禁⽌让变量命名产⽣歧义或误
    导,如将⼀个UIButton命 名为view,将⼀个NSArray命名为dic等,⽰
    例:


    image.png
    3.2.类、协议命名

    类的命名以前缀开始,如:Cass,除前缀外的第⼀单词⾸字母也需要⼤
    写,多个单词以单词 ⾸字母⼤写进⾏分割。类的命名⾸先应保证表
    达意思明确,能⼀眼看出这个类是做什么任务 的,然后才考虑名字
    的长度(不要怕长)。
    协议的命名和类基本相同,协议命名末尾⼀般加上单词delegate来表
    ⽰这是个代理协议的名 称,⼤部分情况下协议名可以直接在其相应
    的类名的尾部加上Delegate即可,⽰例:
    类名:AFHTTPRequestOperationManager,QMEmptyManager 协议
    名:GADAppEventDelegate,GADBannerViewDelegate,
    QMSegmentContainerDelegate

    3.3.枚举的命名名

    枚举类型的命名与类相似,以前缀开始,如:Cass,除前缀外的第⼀单
    词⾸字母也需要⼤
    写,多个单词以单词⾸字母⼤写进⾏分割。
    枚举值的命名是在枚举类型之后加上表⽰该值的⼀个或多个单词,每
    个单词⾸字母⼤写。⽰例如下:


    image.png

    枚举值的确定可以使⽤默认的数值,也可参照系统很多枚举的赋值,
    采⽤移位的⽅法来赋值,这样做的好处在于,可以使⽤按位或和按位
    与来进⾏逻辑判断和赋值,简化代码的编写。(不强制)

    image.png
    3.4.宏和常量的命名

    宏的命名全部为⼤写,为了避免跟第三⽅的宏定义冲突,宏定义全部
    以CS_开头,多个单词之间⽤下划线(_)分割。可以参考系统⾃带宏的
    命名,命 名单词应该表达出该宏表⽰的是个什么值,⽰例:


    image.png

    常量的命名和变量基本⼀致,只是需要⽤⼩写字母k作为前缀,⾸字
    母⼤写来分割单词。


    image.png

    注:常量和宏的定义放在当前⽂件的顶部,不要放在⽂件中间,以⽅
    便查看。

    NSNotification

    当你定义你自己的 NSNotification 的时候你应该把你的通知的名字定义为一个字符串常量,就像你暴露给其他类的其他字符串常量一样。你应该在公开的接口文件中将其声明为 extern 的, 并且在对应的实现文件里面定义。

    因为你在头文件中暴露了符号,所以你应该按照统一的命名空间前缀法则,用类名前缀作为这个通知名字的前缀。

    同时,用一个 Did/Will 这样的动词以及用 "Notifications" 后缀来命名这个通知也是一个好的实践。

    // Foo.h
    extern NSString * const ZOCFooDidBecomeBarNotification
    
    // Foo.m
    NSString * const ZOCFooDidBecomeBarNotification = @"ZOCFooDidBecomeBarNotification";
    
    3.5.⽅法函数命名

    ⽅法名的⾸字母⼩写,且以⾸字母⼤写的形式分割单词,⽅法名和参
    数加起来应该尽可能的
    像⼀句话,能够清晰的表达出这个⽅法所要完成的功能,⽰例:


    image.png
    3.6.扩展(category)命名

    category的命名和类基本⼀致,以Cass为前缀,⾸字母⼤写,category
    的命名应该体现 出该扩展主要功能。


    image.png

    注意: ⽅法命名规则以 cass_

    3.7.⽂件夹⽬录命名规范(待定)
    3.8.资源图⽚命名

    login_cancel_selected, login_cancel_normal,
    arrow_right_white(gray)
    资源图⽚业务或者页⾯进⾏分组,每组建⼀个folder,其名称为对应
    业务功能或页⾯名称, 所有⽂件夹以及图⽚的名称禁⽌使⽤中⽂,
    只能使⽤英⽂字符。
    资源图⽚的命名规则为:业务/页⾯图⽚名称状态。 业务/页⾯:为图
    ⽚所对应的业务或页⾯名称,⾸字母⼩写并以⾸字⼤写的形式分割多
    个单 词;图⽚名称:为图⽚真实名称,⾸字母⼩写并以⾸字⼤写的形式
    分割多个单词;
    状态:主要包含三种:正常、按下、选中,分别⽤normal、pressed、
    selected来标记,在没 有不同状态,即只有正常状态的情况下可以省
    略状态这⼀栏,⽰例:
    ➢ 在navigationBar上的菜单按钮图标和返回按钮图标可以分别命名如
    下: nav_menu_normal nav_menu_selected
    ➢ 没有消息,没有订单时空态页⾯上显⽰的图⽚,可以统⼀定为“空 态”这个业务,且这些 图⽚没有多种状态,故可以省略状态⼀栏:
    empty_message empty_order
    ➢ 登陆时输⼊框的背景图⽚可以命名为: login_boxBackground

    4.注释

    4.1.注释的格式

    在头⽂件,即.h⽂件中添加的注释,包括类、属性、⽅法等的注释应
    该使⽤xcode的标准⽅ 式,这样可以⽅便在别的⽂件中使⽤到该类或
    其属性或⽅法时,可以通过option+单击快速 查看其注释。
    标准注释格式可以由xcode的插件直接⽣成,对于⽐较简短的注释,
    建议直接⽤如下格式,, 会更加简洁:
    /** 注释内容 */,如:


    image.png
    4.2.类的注释

    在每个类的头⽂件的顶部,添加注释,简单的说明这个类是完成什么功能的,如果在新的版
    本开发对类进⾏⽐较重要的修改,也应该简单的注释下在哪个版本做了哪些修改,便于以后
    维护代码时能够更多的定位问题:


    image.png
    4.3.属性和⽅法的注释

    对暴露在头⽂件中的属性和⽅法进⾏注释,以告诉以便在调⽤这些属
    性和⽅法进⾏查看:


    image.png
    4.4.⼀些必要的注释

    对于⼀些逻辑⽐较复杂的代码,应该添加必要的注释,⽅便⾃⼰和他
    ⼈以后维护代码,⽰例:


    image.png

    对于枚举类型的每⼀个枚举值应该给出注释:


    image.png

    5.注意

    5.1.不要在dealloc⽅法和init⽅法中调⽤属性

    不要在dealloc和init⽅法中使⽤属性,即不要使⽤self.name这样的⽅
    式,⽽应该使⽤ _name。理由可以参考:http://blog.devtang.com/blog/
    2011/08/10/do-not-use-accessor-in- init-and-dealloc-method

    5.2.NSString类型的属性声明为copy

    假设将A中的⼀个MutableString给B中的⼀个Property(NSString类型)赋
    值,⾸先是能接受 的,⽗类可以接受⼦类,如果是retain,仅仅是⽣
    成⼀个指针,计数器加⼀,然后指向那个 MutableString。如果
    MString改变,B中那个跟着改变,因为是同⼀块内存区域。⽽选择
    Copy相当于又⽣成了⼀个NSString,与A中的MutableString独⽴。

    5.3. UITableView代理在dealloc中将delegate置为nil

    虽然⽬前已使⽤ARC管理内存,但是仍然需要在dealloc⽅法中将
    UITableView, UIWebView,UICollectionView等类型实例的
    delegate,dataSource置为nil。因为这些属性使⽤ 的是assign⽽不是
    weak,所以在其指向的对象被释放时,它们不会⾃动置为nil。

    5.4.提前释放NSTimer对象

    会循环使⽤的Timer(指定了repeat参数为YES),必须要在合适的时机
    调⽤invalidate⽅ 法,否则会出现内存泄漏,在使⽤类的析构函数中
    调⽤Timer的invalidate⽅法为时已晚,因为timer会对其传递的⽬标
    object增加引⽤计数,若不调⽤invalidate,使⽤类根本得不到析构。
    加runloop

    5.5.头⽂件暴露最少的接⼜

    头⽂件中应该暴露最少的接⼜,只将真正需要供其他类调⽤的⽅法和
    属性暴露在头⽂件中。

    5.6.只引⼊需要的头⽂件

    在每个⽂件中应该引⽤尽量少的头⽂件,不要引⼊⽤不到的类,也不
    要重复引⽤头⽂件,当⽂件有修改时记得查看是否有已不再不需要引
    ⽤的头⽂件,及时移除。

    5.7.NSNotiIication的注册与卸载

    NSNotification的注册应该放到init⽅法中,为了监听到所有通知,应
    该将注册通知的时机尽
    量提前,⽽init⽅法是可以注册通知的最早时间点。 在对象被释放
    时,应该取消其监听的所有通知,所有应该在dealloc⽅法中调⽤
    [[NSNotificationCenter defaultCenter] removeObserver:self]等⽅法来卸
    载通知。

    5.8.⽤枚举替换数字

    对于商品状态,⽹络请求错误类型,UIView及其⼦类的tag等,由不
    同数值进⾏区分的情 况,⼀律使⽤枚举,不允许直接使⽤数字进⾏
    编码。

    5.9.switch/case的使⽤

    每⼀个case必须有⼀个break,如果的确有特殊业务需求不需要break
    的,需要明确的注释说明;必须要有⼀个default分⽀,哪怕default分⽀
    什么也不做,也要写上break;每⼀个分⽀ 都⽤⼤括号括起来。


    image.png
    5.10.调⽤super⽅法

    在⾃定义以下⽅法时,必须调⽤其super⽅法: UIViewController相关⽅
    法:
    viewDidLoad、viewWillAppear、viewDidAppear、
    viewWillDisappear、 viewDidDisappear、viewWillLayoutSubviews、
    viewDidLayoutSubviews等。
    UIView相关⽅法:layoutSubviews UITableViewCell/
    UICollectionViewCell相关⽅法:prepareForReuse

    6.安全性

    6.1 不能⽤NSLog(⽤DLog代替)
    6.2 不能⽤Alert(⽤到⽤Debug) 调试
    6.3 NSArray, NSDictionry基础数据. 相关⽅法使⽤Safe api

    相关规范1:objc禅翻译

    相关规范2:Google 开源项目风格指南

    相关文章

      网友评论

        本文标题:iOS - 编码规范

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