命名规范
原则: 防止命名冲突、可读性高
方式: 驼峰式命名法
说明: 每个模块都需要加上前缀
一、常量命名
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即可