iOS代码规范

命名规范

原则: 防止命名冲突、可读性高
方式: 驼峰式命名法
说明: 每个模块都需要加上前缀

一、常量命名

1.1 在常量前边加上字母k作为标记

static const NSTimeInterval kAnimationDuration = 0.3

1.2 定义作为NSDictionary或者NSNotification的key值字符串时加上const关键字

NSString *const UIApplicationDidEnterBackgroundNotification

1.3 若常量作用域超出.m文件,需要在类外可见时,使用extern关键字,并加上类名前缀

extern NSString *const PGThumbnailSize

1.4 全局常量包括 通知 或者 关键字 都尽可能使用const定义
Tips


  • 使用宏定义可能导致宏被 重定义,引用不同的文件可能导致 宏不同
  • #define 也需要添加k前缀

二、枚举命名
2.1 枚举类型 命名要加相关类名前缀并且 枚举值命名 要加枚举类型前缀,示例如下

typedef NS_ENUM(NSInteger, UIViewAnimationTransition) {
    UIViewAnimationTransitionNone,
    UIViewAnimationTransitionFlipFromLeft,
    UIViewAnimationTransitionFlipFromRight,
    UIViewAnimationTransitionCurlUp,
    UIViewAnimationTransitionCurlDown,
};

typedef NS_OPTIONS(NSUInteger, UIControlState) {
    UIControlStateNormal       = 0,
    UIControlStateHighlighted  = 1 << 0,
    UIControlStateDisabled     = 1 << 1,
};

优点:增强类型检查,更好的代码可读性
三、 变量和对象的命名
方式: 修饰+类型

@property (nonatomic, strong) UILabel *titleLabel; //表示*标题*的label,是*UILabel*类型
@property (nonatomic, strong) UIButton *confirmButton; //表示*确认*的button,是*UIButton*类型

对于BOOL类型,需要加is前缀

- (BOOL)isEqualToString:(NSString *)aString;
- (BOOL)hasPrefix:(NSString *)aString;

四、 方法命名
4.1 添加 参数 提示

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

4.2 回调方法通知方法 的命名
原则: 动作发生之前用Will,发生之后用Did,询问是否发生用Should

- (nullable NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath;  //将要选择这一行cell
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath; //已经选择这一行cell
- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(6_0); //是否高亮(选择这一行cell)

4.3 回调方法第一个参数是调用者

- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions;
- (void)buttonTapped:(UIButton*)sender;

4.4 方法符合语法
大部分方法可以分为两类:要什么做什么


  • 要什么
    表示取得某个对象,要以名词作为方法的开头
- (UIImage *)imageNamed:(NSString *)name;

  • 做什么
    表示执行某种操作,要以动词作为方法开头
- (void)setUpNavBar

书写规范

一、 ViewController 书写规范
1.1 方法书写顺序(依次)

* 生命周期  
* 基类public方法  
* 代理方法  
* 本类private方法  
* 通知方法  
* 请求方法  
二、*代码目录分类* 规范  
2.1 总代码目录架构  
![](http://upload-images.jianshu.io/upload_images/59913-5dd33a1c3e43b2fc.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

2.2 Managers 目录  
![](http://upload-images.jianshu.io/upload_images/59913-c0b2dd78ed275195.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)  
2.3 Models 目录  
![](http://upload-images.jianshu.io/upload_images/59913-e0d7c9a4bbb55550.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)  
2.4 Controllers 目录  
![](http://upload-images.jianshu.io/upload_images/59913-176279229c98d2ee.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)  
2.5 General 目录  
![](http://upload-images.jianshu.io/upload_images/59913-4dfbc152ac0b9745.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)  
2.6 Macros 目录  
![](http://upload-images.jianshu.io/upload_images/59913-feffc82e7f96feb0.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)  
2.7 Vendors 目录  
![](http://upload-images.jianshu.io/upload_images/59913-e137531eda752764.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)  
2.8 Assets.xcassets 目录  
![](http://7xpu01.com1.z0.glb.clouddn.com/Assets.xcassets%E7%9B%AE%E5%BD%95.png)  
三、 写码规范  
3.1 判断**nil**或者**YES/NO**  

```javascript
if (obj) 
  { 
    //... 
  }
if (!obj) 
  { 
    //... 
  }

3.2 NSArray NSDictionary 初始化方法

NSArray *contacters = @[@"Allen", @"Bob", @"Chirs"];
NSDictionary *bookInfo = @{@"BookName":@"iOS开发之进阶篇", @"BookPrice":@"999999.0RMB", @"BookAuthor":@"RenSihao"};
NSNumber *isHide = @NO;
NSNumber *errorCode = @404;

优点:简洁明了,同时防止初始化进去一个nil

3.3 定义属性尽可能写全参数

@property (nonatomic, readwrite, copy) NSString *name;
  • 如果是内部使用的属性, 需定义成该类的私有属性(写在.m文件的class extension里)
  • 对于拥有Mutable子类型的对象, 例如NSString NSArray NSDictionary NSDictionary, 一定要定义成copy属性
  • 尽量不要暴露mutable类型的对象在public interface, 建议在.h定义一个Inmutable类型的属性, 然后在.m的get函数里面返回一个内部定义的mutable变量
  • 不要出现混合声明,尽可能都使用@property声明
    3.4 BOOL类型赋值
BOOL isAdult = age > 18;
 

3.5 拒绝死值

if (country = Countries.China) 
  { //... }
const int adultAge = 18;
if (age > adultAge)
  { //... }

3.6 复杂的条件判断
如果判断较为复杂,尽可能写到一个方法里

if ([self canDeleteAccount:account])
    { //... }
/**
 method
*/
- (BOOL)canDeleteAccount:(account)
{
    if (account.balance == 0  || account.owner.isDead == YES || account.isCancel == YES)
    {
        return YES;
    }
    else
    {
        return NO;
    }
}

3.7 嵌套判断

if (!user.account) return NO;
if (!user.password) return NO;
return YES;

3.8 使用Block避免循环引用

  • block内部使用外部声明的强引用去访问对象A,则block内部会产生一个强引用指向对象A
  • block内部使用外部声明的弱引用去访问对象A,则block内部会产生一个弱引用指向对象A
__weak typeof(self) weakSelf = self;
obj.block = ^ {
    __strong typeof(self) strongSelf = self;
    if (strongSelf)
    {
        [strongSelf doSomething]; //strongSelf != nil
    }
    else 
    {
        //maybe nothing...
        return ;
    }
}

3.9 宏的格式
宏要写成大写至少一个字母大写,全部小写有时候Xcode不会自动提示
3.10 加载xib
加载xib名称使用 NSStringFromClass()

[self.tableView registerNib:[UINib nibWithNibName:NSStringFromClass([UserListCell class]) bundle:nil] forCellReuseIdentifier:ID];

3.11 继承
子类继承父类方法,需要重写一定要先调用父类进行初始化操作
建议在父类方法后追加 NS_REQUIRES_SUPER ,作用是子类重写这个方法就会自动警告提示要调用这个super方法

- (void)addAllNotifications;

3.12 命名控件避开系统命名
例如

@property (nonatomic, strong) UILabel *textLabel; //错误命名
@property (nonatomic, strong) UILabel *contentLabel; //正确命名

3.13 id类型
id类型属性调用不能用点语法, 调用get方法只能用中括号

[id 方法名]

3.14 判断if书写方式

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.row == 0) return 40;
    if (indexPath.row == 1) return 50;
    if (indexPath.row == 2) return 60;
    return 44;
}

3.15 快速调试
需要注释掉一个方法,在该方法内部第一行return即可,无需大段注释
3.16 监听键盘通知
使用

UIKIT_EXTERN NSString *const UIKeyboardWillChangeFrameNotification

优点:无论键盘切换输入法,切换表情等原因导致frame更改,该通知一定会监听得到
3.17 通知命名
使用const修饰,以Notification结尾
3.18 BOOL类型属性
如果是声明BOOL类型,建议在括号中重写get方法

@property (nonatomic, readonly, getter = isKeyWindow) BOOL keyWindow;

3.19 自定义方法
不能使用and这个单词连接参数

- (instancetype)initWithWidth:(CGFloat)width height:(CGFloat)height;

3.20 点语法
尽可能使用点语法访问属性,但是访问其他实例对象使用括号

view.backgroundColor = [UIColor redColor];
[UIApplication sharedApplication].delegate; //推荐

[view setBackgroundColor:[UIColor redColor]];
UIApplication.sharedApplication.delegate; //不推荐

3.21 引用头文件
类的头文件(.m文件)尽量不要引用其他头文件,无需知道类的内部细节使用@class即可


你可能感兴趣的:(iOS代码规范)