Powered by md-Blog  文 - 篇  访客 -

iOS开发代码规范


  分类:iOS开发  / 
更新:2020-11-10 15:02:04  /  创建:2020-01-13 16:54:53
不要删除

iOS开发代码规范

概述

公司外包项目日渐增多,为了规范项目代码风格使项目易于维护和交叉开发,以下规定相关规范要求,我们把开发规范暂时划分成两个等级,分别是【必须】、【建议】。

  • 【必须】:必须遵守。是不得不遵守的约定,一旦违反极有可能引起严重后果。
  • 【建议】:建议遵守。长期遵守这样的约定,有助于维护系统的稳定和提高合作效率。

1. 命名规则

1.1 通用命名规则

【必须】项目宏和字符常量的命名


//通用宏定义  以小写k开头的驼峰法命名
#define kBaseServerURL    @"xxxxx" 

//NSUserDefault 的Key 必须以UDKey_开头
UDKey_LoginUserInfo

//NSNotification 的key 必须以NNKey_开头
NNKey_UserStatusChanged

//类型枚举以Ty开头
typedef NS_ENUM(NSInteger, TyPayWay) {
    TyPayWayUnion = 1, //银行卡支付
    TyPayWayAlipay,    //支付宝支付
    TyPayWayCoin,  //积分支付
    TyPayWayWechat //微信
};

//全局prompt提示语宏定义,以kPrompt_开头
#define kPrompt_Timeout @"网络连接超时,等会儿再试试…"

【必须】自我描述性。属性/函数/参数/变量/常量/宏 的命名必须具有自我描述性。杜绝过度缩写、或者无意义的命名方式。

【必须】驼峰命名方式。参数名、成员变量、局部变量、属性名都要采用小写字母开头的驼峰命名方式。
如果方法名以一个众所周知的大写缩略词开始,可以不适用驼峰命名方式。比如FTP、WWW等。
如果Model类中因为服务端参数以【xxx_xxxx】方式命名,为了快速开发实现Model迭代可以跟服务端返回参数一样。

【必须】清晰性。属性/函数/参数/变量/常量/宏 的命名应该保持清晰+简洁,如果鱼和熊掌不能兼得,那么清晰更重要。

命名说明
insertObject:atIndex:规范的写法
insert:at:不清晰,插入什么?at代表什么?
removeObjectAtIndex:规范的写法
removeObject:规范的写法,因为参数指明了要移除一个对象
remove:不清晰,移除什么?

【建议】一般情况下,不要缩写或省略单词,建议拼写出来,即使它有点长。当然,在保证可读性的同时,for循环中遍历出来的对象或者某些方法的参数可以缩写。

命名说明
destinationSelection规范写法
destSel不清晰
setBackgroundColor :规范写法
setBkgdColor:不清晰

1.2 Method命名规范

【必须】方法名也要采用小写字母开头的驼峰命名方式。如果方法名以一个中所周知的大写缩略词开头(比如HTTP),该规则可以忽略。

【建议】一般情况下,不要在方法名称中使用前缀,因为他存在于特定类的命名空间中。

【必须】禁止在方法前面加下划线“ _ ”。Apple官网团队经常在方法前面加下划线"_"。为了避免方法覆盖,导致不可预知的意外,禁止在方法前面加下划线。

【必须】自我描述性。方法的命名也应该具有自我描述性。杜绝过度缩写、或者无意义的命名方式。

【必须】苹果爸爸说:如果一个方法代表某个名词执行的动作,则该方法应该以一个动词开头。如下:

- (void)invokeWithTarget:(id)target;
- (void)selectTabViewItem:(NSTabViewItem *)tabViewItem

【必须】不要使用“do”或者"does"作为方法名称的一部分,因为这些助动词不能为方法名称增加太多的意义,反而让方法看起来更加臃肿。同时,也请不要在动词前面使用副词或者形容词。

【建议】参数之前的单词尽量能描述参数的意义。

命名说明
- (id)viewWithTag:(NSInteger)aTag;OK
- (id)taggedView:(int)aTag;不OK

1.3 Category命名规范

【必须】category中不要声明属性和成员变量。

【必须】避免category中的方法覆盖系统方法。可以使用前缀来区分系统方法和category方法。但前缀不要仅仅使用下划线”_“。

【建议】如果一个类比较复杂,建议使用category的方式组织代码。具体可以参考UIView。

2. 编码规范

2.1 UIViewController 规范

#pragma mark - Lifecycle
- (instancetype)init {}
- (void)dealloc {}
- (void)viewDidLoad {}
- (void)viewWillAppear:(BOOL)animated {}

#pragma mark - LoadData
- (void)loadData {}
- (void)loadMoreData{}

#pragma mark - Public
- (void)publicMethod {}
- 
#pragma mark - Private
- (void)privateMethod {}

#pragma mark - IBActions
- (IBAction)submitData:(id)sender {}

#pragma mark - UITableViewDataSource

#pragma mark - UITableViewDelegate

#pragma mark - OtherDelegate

#pragma mark - Get & Set
- (void)setCustomProperty:(id)value {}
- (id)customProperty {}

#pragma mark - NSObject
- (NSString *)description {}

【必须】UIViewController生命周期相关方法一定要放在最上面,不能中间插入自定义方法。

【必须】UIViewController方法要分门别类并使用mark标记区分。
#pragma mark - life style

【必须】公有属性写在.h文件中,私有属性写在.m文件的扩展interface中。

2.1 Block规范**

【必须】调用block时需要对block判空。

【必须】注意block潜在的引用循环。

2.2 Notification规范**

【必须】在每个应用中,我们应该时刻留意并控制通知的数量,避免通知满天飞的现象。当我们使用通知时,必须要思考,有没有更好的办法来代替这个通知。禁止遇到问题就想到通知,把通知作为备选项而非首选项。

【必须】post通知时,object通常是指发出notification的对象,如果在发送notification的同时要传递一些额外的信息,请使用userInfo,而不是object。

【必须】在多线程应用中,Notification在哪个线程中post,就在哪个线程中被转发,而不一定是在注册观察者的那个线程中。如果post消息不在主线程,而接受消息的回调里做了UI操作,需要让其在主线程执行。

3. UI规范

【必须】类属性中的IBOutlet属性应该能一下子提现出所属UI类,比如
titleLabel
shareButton
avatarImageView
nameTextfield
contentTextView

【必须】如果想要获取window,不要使用view.window获取。请使用[[UIApplication sharedApplication] keyWindow]。

【建议】当访问一个CGRect的x,y,width,height时,应该使用CGGeometry函数代替直接访问结构体成员。
因此,推荐的写法是这样的:

CGRect frame = self.view.frame;
CGFloat x = CGRectGetMinX(frame);
CGFloat y = CGRectGetMinY(frame);
CGFloat width = CGRectGetWidth(frame);
CGFloat height = CGRectGetHeight(frame);

反对这样的写法:

CGRect frame = self.view.frame;
CGFloat x = frame.origin.x;
CGFloat y = frame.origin.y;
CGFloat width = frame.size.width;
CGFloat height = frame.size.height;

4. 代码注释规范

【必须】如果方法、函数、类、属性等需要提供给外界或者他人使用,必须要加注释说明。

【必须】如果你的代码以SDK的形式提供给其他人使用,那么接口的注释是必须的。必须对暴露给外界的所有方法、属性、参数加以注释说明。

【建议】注释应该说明其作用以及注意事项(如果有)。

【建议】因为方法或属性本身就具有自我描述性,注释应该简明扼要,说明是什么和为什么即可。

5. 类的设计规范

【建议】尽量减少继承,类的继承关系不要超过3层。可以考虑使用category、protocol来代替继承。

【建议】把一些稳定的、公共的变量或者方法抽取到父类中。子类尽量只维持父类所不具备的特性和功能。

【建议】.h文件中只暴露出一些必要的类、公开的方法、只读属性;私有类、私有方法和私有属性以及成员变量,尽量写在.m文件中。


不要删除