博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS 代码规范
阅读量:5918 次
发布时间:2019-06-19

本文共 7218 字,大约阅读时间需要 24 分钟。

概述

命名的好坏在开发中往往也不怎么重视,毕竟差的命名也不会影响程序逻辑。但是不好的命名在大项目中带来的隐形维护成本是相当高的,这些在项目开始时可能还很难察觉,而后来会陷入前仆后继的维护困境中。我们往往非常重视项目逻辑的复杂性,却不能好好的把“简单”的命名做好。其实,如果简单的东西都做不好,那么做出再复杂的东西那也是垃圾。

命名规范

分类(类别)命名

与类命名相同,此外需添加要扩展的类名和“+”

举例:NSString+URLEncoding

协议(委托)命名

与类命名相同,此外需添加“Delegate”后缀

举例:ReplyViewDelegate

方法命名

首字母小写,之后每个单词首字母都大写

方法名使用动词短语

举例:- (void)setupPostWithValue:(int)value

“要什么”往往被胡乱命名为get开头的方法。首先get是一个动词,所以它还是“做什么”或者说“做的是要什么”。那么get方法不要用于返回对象,但它可用于参数。

- (XXItem *)getItemAtIndex:(NSUInteger)index                  //Bad!! 不规范的命名- (XXItem *)itemAtIndex:(NSUInteger)index                     //Good, 命名清晰- (void)getItem:(XXItem **)outItem atIndex:(NSUInteger)index  //比较符合规范,但第二种更好。

参数命名

首字母小写,之后每个单词首字母都大写

每个参数前要加参数的名称提示

举例:

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil- (void)performSegueWithIdentifier:(NSString *)identifier sender:(id)sender

对象命名

采用修饰+类型的方式

举例:

titleLabel    //表示标题的label,  是UILabel类型confirmButton //表示确认的button, 是UIButton类型

图片命名

使用英文,全部小写 ,添加模块名作为前缀,避免冲突 。图片应该与类文件一样,按模块分组放置

举例:

Home(界面名称)_(功能属性简写+描述).png

如: home_btn_recommended.png 

或:

compose_mentionbutton_background@2x.png

compose_mentionbutton_background_highlighted@2x.png

分组命名

使用英文,首字母大写,之后每个单词首字母都大写

每个分组使用模块的名字

使用的开源库统一放在“Library”分组下

使用的公共组件统一放在“Common”分组下

使用资源统一放在"Resource"分组下,包括文件、音频、图片、证书等

编码规范 

编码规范简单来说就是为了保证写出来的代码具备三个原则:可复用, 易维护, 可扩展. 这其实也是面向对象的基本原则. 可复用, 简单来说就是不要写重复的代码, 有重复的部分要尽量封装起来重用。

判断nil或者YES/NO

推荐:

if (someObject) { ... } if (!someObject) { ... }

不推荐:

if (someObject == YES) { ...} if (someObject != nil) { ...}

if (someObject == YES)容易误写成赋值语句

条件赋值

推荐:

result = object ? : [self createObject];

不推荐:

result = object ? object : [self createObject];

如果是存在就赋值本身, 简洁。

BOOL赋值

推荐:

BOOL isAdult = age > 18;

不推荐:

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

拒绝死值

推荐:

if (car == Car.Nissan)orconst int adultAge = 18; if (age > adultAge) { ... }

不推荐:

if (carName == "Nissan")orif (age > 18) { ... }

死值每次修改的时候容易被遗忘, 地方多了找起来就悲剧了. 而且定义成枚举或者static可以让错误发生在编译阶段. 另外仅仅看到一个数字, 完全不知道这个数字代表的意义. 纳尼?

复杂的条件判断

推荐:

if ([self canDeleteJob:job]) { ... }         - (BOOL)canDeleteJob:(Job *)job{    BOOL invalidJobState = job.JobState == JobState.New                          || job.JobState == JobState.Submitted                          || job.JobState == JobState.Expired;    BOOL invalidJob = job.JobTitle && job.JobTitle.length;         return invalidJobState || invalidJob;}

不推荐:

if (job.JobState == JobState.New    || job.JobState == JobState.Submitted    || job.JobState == JobState.Expired    || (job.JobTitle && job.JobTitle.length)){    //....}

清晰明了, 每个函数DO ONE THING!

嵌套判断

推荐:

- (void) someMethod {  if (![someOther boolValue]) {      return;  }  //Do something important}

不推荐:

- (void) someMethod {  if ([someOther boolValue]) {      //Do something important  }}

一旦发现某个条件不符合, 立即返回, 条理更清晰。

所有的逻辑块必须使用花括号包围,即使条件体只需编写一行代码也必须使用花括号

推荐:

if (!error) {    return success;}

不推荐:

if (!error)    return success;...if (!error) return success;

参数过多

推荐:

- (void)registerUser(User *user){     // to do...    }

不推荐:

- (void)registerUserName:(NSString *)userName                password:(NSString *)password                    email:(NSString *)email{     // to do...}

当发现实现某一功能需要传递的参数太多时, 就预示着你应该聚合成一个model类了...这样代码更整洁, 也不容易因为参数太多导致出错。

点标记语法

属性和幂等方法(多次调用和一次调用返回的结果相同)使用点标记语法访问,其他的情况使用方括号标记语法。

推荐:

view.backgroundColor = [UIColor orangeColor];[UIApplication sharedApplication].delegate;

不推荐:

[view setBackgroundColor:[UIColor orangeColor]];UIApplication.sharedApplication.delegate;

枚举

枚举使用Objective-C方式来定义,枚举命名是 类前缀+枚举名,枚举值要加枚举名。

举例:

typedef NS_ENUM(NSUInteger, HGMachineState) {    HGMachineStateNone,    HGMachineStateIdle,    HGMachineStateRunning,    HGMachineStatePaused};

常量

常量应该类名称+“骆峰式”单词大写。

推荐:

static const NSTimeInterval HGSignInViewControllerFadeOutAnimationDuration = 0.4;

不推荐:

static const NSTimeInterval fadeOutTime = 0.4;

常数是优于串联字符串或数字的,允许多个地方使用常用变量,可以迅速改变不需要查找和替换。常量应该声明为静态常量而不使用宏定义,除非明确需要定义一个宏。

推荐:

static NSString * const ZOCCacheControllerDidClearCacheNotification = @"ZOCCacheControllerDidClearCacheNotification";static const CGFloat ZOCImageThumbnailHeight = 50.0f;

不推荐:

#define CompanyName @"Apple Inc."#define magicNumber 42

单例模式

使用GCD代替使用sharedInstance,每次调用+ (id)sharedInstance函数都会付出取锁的代价。

推荐:

+ (instancetype)sharedInstance{   static id sharedInstance = nil;   static dispatch_once_t onceToken;   dispatch_once(&onceToken, ^{      sharedInstance = [[self alloc] init];   });   return sharedInstance;}

不推荐:

+ (instancetype)sharedInstance{    static id sharedInstance;    @synchronized(self) {        if (sharedInstance == nil) {            sharedInstance = [[MyClass alloc] init];        }    }    return sharedInstance;}

代理

定义一个协议是 类名+Delegate,并要使用weak 弱指针,协议使用可选@optional

@class ZOCSignUpViewController;@protocol ZOCSignUpViewControllerDelegate 
@required- (void)signUpViewController:(ZOCSignUpViewController *)controller didProvideSignUpInfo:(NSDictionary *);@optional- (void)signUpViewControllerDidPressSignUpButton:(ZOCSignUpViewController *)controller;@end@interface ZOCSignUpViewController : UIViewController@property (nonatomic, weak) id
delegate;@end

在发送委托代理方法之前,一定要先检查该委托方法已经被实现(否则会崩溃)。

if ([self.delegate respondsToSelector:@selector(signUpViewControllerDidPressSignUpButton:)]) {    [self.delegate signUpViewControllerDidPressSignUpButton:self];}

动画

推荐

[UIView animateWithDuration:1.0                 animations:^{                     // something                 }                 completion:^(BOOL finished) {                     // something                 }];

不推荐

[UIView animateWithDuration:1.0 animations:^{    // something } completion:^(BOOL finished) {    // something}];

Pragma Mark

使用“#pargma mark - ”实现方法的分组。建议按下面几点单独分组:

1.功能分组

2.代理协议实现分组

3.重写父类方法

- (void)dealloc { /* ... */ }- (instancetype)init { /* ... */ }#pragma mark - View Lifecycle- (void)viewDidLoad { /* ... */ }- (void)viewWillAppear:(BOOL)animated { /* ... */ }- (void)didReceiveMemoryWarning { /* ... */ }#pragma mark - Custom Accessors- (void)setCustomProperty:(id)value { /* ... */ }- (id)customProperty { /* ... */ }#pragma mark - IBActions- (IBAction)submitData:(id)sender { /* ... */ }#pragma mark - Public- (void)publicMethod { /* ... */ }#pragma mark - Private- (void)zoc_privateMethod { /* ... */ }#pragma mark - UITableViewDataSource- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { /* ... */ }#pragma mark - ZOCSuperclass// ... overridden methods from ZOCSuperclass#pragma mark - NSObject- (NSString *)description { /* ... */ }

抽象方法定义

在Componens中有很多的抽象类,因为Objective-C没有语法限定抽象类,所以我们约定一下抽象类的注释和声明方法。
在类注释中声明该类为抽象类,抽象方法必须为公开方法,并添加#pragma标记注释 
@interface TestClass : NSObject#pragma mark - Abstract Method//抽象方法-(void)doWork;@end

抽象类不允许被实例化,所以需要在init方法中添加判断代码

@implementation TestClass- (id)init {    if( [self class] == [TestClass class]) {        @throw [NSException exceptionWithName:@"抽象类无法实例化" reason:@"抽象类无法实例化: TestClass" userInfo:nil];    }    else {        self = [super init];        if(self){                    }        return self;    }}#pragma mark - Abstract Method- (void)doWork {    @throw [NSException exceptionWithName:@"抽象方法没有被实现" reason:@"抽象方法没有被实现: doWork" userInfo:nil];}@end

 

参数链接:

 

转载地址:http://amfvx.baihongyu.com/

你可能感兴趣的文章
【21】Python100例基础练习(5)
查看>>
Tips Tips
查看>>
spring项目的 WebApplicationContext 初始化两次的解决方法
查看>>
CLOUD 02: elk
查看>>
Python写的Web spider(网络爬虫)
查看>>
Android之Toast通知的几种自定义用法
查看>>
zimbra邮件搭建
查看>>
kvm虚拟化学习笔记(十五)之kvm虚拟机动态迁移
查看>>
使用eval和loop在模版中直接读取数据库内容并输出
查看>>
云计算开源英雄集结令!五项定制大奖等你来战
查看>>
RIP
查看>>
yum安装报错
查看>>
python之万维网
查看>>
LAMP 环境搭建实例
查看>>
解决MySQL不支持InnoDB
查看>>
eclipse和maven创建WebApp项目
查看>>
jquery的attr和prop区别之实例
查看>>
grep小练习
查看>>
隆文互动营销研究院服务的企业微博再创新高
查看>>
部署Windows RDS服务
查看>>