- 说两句
项目结构和代码风格的重要性对于一个团队和项目来说不言而喻。首先项目结构清晰合理,方便产品的快速迭代以及提高团队的开发效率;其次统一的规范可以促进团队合作,降低维护成本,以及有助于代码审查,减少bug处理。
以下也只是列举了个大概,只要养成了良好的代码习惯,自然而然就会不断的要求自己,提高自己。
一、项目结构
结构如图所示
结构说明
- Classes
- Extensions - 扩展类
- Common - 项目之间可公用方法
- Global - 项目内公共方法、变量、宏定义
- Manager - 网络请求类、数据库操作类、缓存操作类
- Model - 模型
- ViewModel - 视图模型(视情况需要增加)
- Views - 视图(根据功能模块分出Item)
- Constrollers - 控制器(根据功能模块分出Item)
- Category - 分类
- Frameworks - 系统的框架
- Tookis - 引用的第三方
二、Objective-C代码规范
目录
- 代码结构
- 空格
- 注释
- 命名
- 方法
- 变量
- 常量
- 枚举
- 单例模式
代码结构
//ViewController 生命周期
#pragma mark - Lifecycle
- (void)viewDidLoad {}
- (void)viewWillAppear:(BOOL)animated {}
- (void)didReceiveMemoryWarning {}
//通知事件
#pragma mark - Notificaion
- (void)keyboardWillAppear:(NSNotification *)aNotification {}
//手势方法
#pragma mark - Gesture
- (void)backgroundViewTapGesture:(UITapGestureRecognizer *)sender {}
//按钮以及其他控件Change事件
#pragma mark - Action
- (IBAction)registerButtonHandler:(id)sender {}
//代理事件
#pragma mark - UITextField Delegate
#pragma mark - UITableView Delegate & DataSource
//私有方法
#pragma mark - Private
- (void)initUI {} //UI初始化方法
- (void)loadData {} //加载数据方法
- (void)displayInfo {} //加载完UI显示数据方法
- (void)privateMethod {} //其他私有业务逻辑等方法
//共有方法
#pragma mark - Public
- (void)publicMethod {} //外部调用方法
空格
- 缩进使用4个空格,确保在Xcode偏好设置来设置。
- 方法大括号和其他大括号(if/else/switch/while 等.)总是在同一行语句打开但在新行中关闭。
- 成员变量空格位置
@property (copy, nonatomic) NSString *userName;
- 方法空格位置
//- 后面 and 参数名之间 and 第一个大括号前 需要一个空格
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 2;
}
注释
当需要注释时,注释应该用来解释这段特殊代码为什么要这样做。任何被使用的注释都必须保持最新或被删除。
一般都避免使用块注释,因为代码尽可能做到自解释,只有当断断续续或几行代码时才需要注释。例外:这不应用在生成文档的注释
命名
Apple命名规则尽可能坚持,特别是与这些相关的memory management rules(NARC)。
长的,描述性的方法和变量命名是好的。
变量的命名使用驼峰式。
- 控件命名必须加控件后缀
应该:
UIButton *settingsButton;
不应该:
UIButton *setBut;
- 常见变量命名
@property (copy, nonatomic) NSString *userName;
//数组用List、s、array后缀,推荐List
@property (strong, nonatomic) NSMutableArray *orderList;
//Bool类型用is前缀
@property (assign, nonatomic) BOOL isLogin;
- 静态变量加前缀
应该:
static NSTimeInterval const RWTTutorialViewControllerNavigationFadeAnimationDuration = 0.3;
不应该:
static NSTimeInterval const fadetime = 1.7;
- Model类命名
使用项目前缀,如"KB"-> KBUser
方法
在方法签名中,应该在方法类型(-/+ 符号)之后有一个空格。在方法各个段之间应该也有一个空格(符合Apple的风格)。在参数之前应该包含一个具有描述性的关键字来描述参数。
"and"这个词的用法应该保留。它不应该用于多个参数来说明,就像initWithWidth:height
以下这个例子:
应该:
- (void)setExampleText:(NSString *)text image:(UIImage *)image;
- (void)sendAction:(SEL)aSelector to:(id)anObject forAllCells:(BOOL)flag;
- (id)viewWithTag:(NSInteger)tag;
- (instancetype)initWithWidth:(CGFloat)width height:(CGFloat)height;
不应该:
-(void)setT:(NSString *)text i:(UIImage *)image;
- (void)sendAction:(SEL)aSelector :(id)anObject :(BOOL)flag;
- (id)taggedView:(NSInteger)tag;
- (instancetype)initWithWidth:(CGFloat)width andHeight:(CGFloat)height;
- (instancetype)initWith:(int)width and:(int)height; // Never do this.
变量
- 变量名称采用英文命名且命名所见即所得,明确变量的意义。不得存在拼音或含糊不清的英文表达
- 属性特征要写明
@property (copy, nonatomic) NSString *userName;
@property (strong, nonatomic) NSMutableArray *orderList;
@property (assign, nonatomic) BOOL isLogin;
常量
常量首选内联字符串字面量或数字,因为常量可以轻易重用并且可以快速改变而不需要查找和替换。常量应该声明为 static 常量而不是 #define ,除非非常明确地要当做宏来使用。
推荐:
static NSString * const NYTAboutViewControllerCompanyName = @"The New York Times Company";
static const CGFloat NYTImageThumbnailHeight = 50.0;
反对:
#define CompanyName @"The New York Times Company"
#define thumbnailHeight 2
- UserDefault Key常量
//UserDefalut Key
//使用前缀 kUDKey标明
static NSString * const kUDKeyPrivacySwitchState = @"kUDKeyPrivacySwitchState";
- Notification Key常量
//Notification Key
//使用小写k开头、以及Notification结尾
static NSString * const kAddDiarySucceedNotificaiton = @"kAddDiarySucceedNotificaiton";
枚举
使用NS_ENUM进行枚举,加上前缀
typedef NS_ENUM(NSInteger, KBUserSex) {
KBUserSexMan = 1, //男
KBUserSexWoman = 2, //女
};
单例模式
单例对象应该使用线程安全模式来创建共享实例。
+ (instancetype)sharedInstance {
static id sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}