- 关于命名
1> 统一要求
• 含义清楚,尽量做到不需要注释也能了解其作用,若做不到,就加注释
• 使用全称,不适用缩写
2> 类的命名
• 大驼峰式命名:每个单词的首字母都采用大写字母
例子:MFHomePageViewController
• 后缀要求
ViewController: 使用ViewController做后缀
例子: MFHomePageViewController
View: 使用View做后缀
例子: MFAlertView
UITableCell:使用Cell做后缀
例子: MFNewsCell
Protocol: 使用Delegate或者DataSource作为后缀
例子: UITableViewDelegate
UI控件依次类推
3> 方法命名
• 小驼峰式命名,每一段都以小写字母开头,后面的单词首字母大写
• 要符合英语语法,使方法名简单干练,便于理解,语义通顺
正确示例:
- (NSInteger)heightOfAttributedString:(NSAttributedString *)attributedString byLimitWidth:(CGFloat)limitWidth;
错误示例: - (NSInteger)getAttributedStringHeightWithString:(NSAttributedString )string widthValue:(int)width;
4> 私有变量
• 小驼峰式命名:第一个单词以小写字母开始,后面的单词的首字母全部大写
例子:firstName、lastName
• 以 _ 开头,第一个单词首字母小写
例子:NSString * _somePrivateVariable;
• 私有变量放在 .m 文件中声明
5> property变量
• 小驼峰式命名
例子:
/*
用户名
*/
@property (nonatomic, copy) NSString *userName;
• 禁止使用synthesize关键词
6> 宏命名
• 全部大写,单词间用 _ 分隔。[不带参数]
例子: #define THIS_IS_AN_MACRO @"THIS_IS_AN_MACRO"
• 以字母 k 开头,后面遵循大驼峰命名。[不带参数]
例子:#define kWidth self.frame.size.width
• 小驼峰命名。[带参数]
例子:
define getImageUrl(url) [NSURL URLWithString:[NSString stringWithFormat:@"%@%@",kBaseUrl,url]]
7> Enum
• Enum类型的命名与类的命名规则一致
• Enum中枚举内容的命名需要以该Enum类型名称开头
例子:
typedef NS_ENUM(NSInteger, AFNetworkReachabilityStatus) {
AFNetworkReachabilityStatusUnknown = -1,
AFNetworkReachabilityStatusNotReachable = 0,
AFNetworkReachabilityStatusReachableViaWWAN = 1,
AFNetworkReachabilityStatusReachableViaWiFi = 2
};
8> Delegate命名
• 当另一个对象中可能用到该类的多个实例时,类的实例必须为回调方法的参数之一, 如
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
• 回调方法的参数只有类自己的情况,方法名要符合实际含义, 如:- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
• 以类的名字开头(回调方法存在两个以上参数的情况)以表明此方法是属于哪个类的, 如: - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
• 充分利用动词的不同时态例如did和will通知Delegate已经发生的变化或将要发生的变化, 如:
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath; - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
- 私有方法、属性及变量声明
1> 声明位置
在.m文件中最上方。如果需要显示到头文件,可以使用@private进行修饰。
例子1:
import "ViewController.h"
@interface ViewController ()
// 在这个category(类目)中定义变量和方法
@end
@implementation ViewController {
// 声明私有变量
}
例子2:
@interface ViewController : UIViewController {
@private
NSString *name;
}
- 关于注释
最好的代码是不需要注释的 尽量通过合理的命名
良好的代码把含义表达清楚 在必要的地方添加注释
注释需要与代码同步更新
如果做不到命名尽量的见名知意的话,就可以适当的添加一些注释或者mark
1> 属性注释和方法声明注释
使用系统自带的“option+command+/”
/**
代理方法
@param personID 登录ID
@param password 密码
@param completeHandler 完成回调
*/
- (void)loginWithPersonID:(NSString *)personID password:(NSString *)password completeHandler:(void (^)(checkLogon *result))completeHandler;
- 关于UI布局
推荐使用纯代码写UI,方便其他人修改和理解。除了UITableViewCell,这个类使用xib具有一定的优势。
Xib文件的命名与其对应的.h文件保持相同
Xib文件中控件的组织结构要合理,Xib文件中控件需要有合理的可读性强的命名,方便他人理解 - 格式化代码
1> 指针 "" 位置
定义一个对象时,指针 "" 靠近变量
例子: NSString *userName;
2> 方法的声明和定义
在 - 、+ 和 返回值 之间留一个空格,方法名和第一个参数之间不留空格
- (id)initWithNibName:(NSString *)nibNameOrNilbundle:(NSBundle *)nibBundleOrNil {
…
}
3> 代码缩进
• 使用 xcode 默认缩进,即 tab = 4空格
• 使用 xcode 中 re-indent 功能定期对代码格式进行整理
• 相同类型变量声明需要独行声明
例子:
CGFloat oringX = self.view.frame.origin.x;
CGFloat oringY = self.view.frame.origin.y;
CGFloat lineWidth = self.view.frame.size.width;
• Method与Method之间空一行
例子:
@implementation ViewController
(void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}(void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
4> 对method进行分组
使用 #pragma mark - 方式对类的方法进行分组
例子:
pragma mark – 私有方法
(void)samplePrivateMethod {
//...
}(void)sampleForIf {
//...
}(void)sampleForWhile {
//...
}(void)sampleForSwitch {
//...
}(void)wrongExamples {
//...
}
pragma mark – 公有方法
- (void)samplePublicMethodWithParam:(NSString*)sampleParam {
//...
}
pragma mark – 生命周期
(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
//...
}(void)viewDidLoad {
//...
}(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
//...
}
5> 大括号写法
• 左括号在方法名后隔一个空格
例子:(void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
• 任何需要写大括号的部分,不得省略
错误示例:(void)wrongExamples {
BOOL someCondition = YES;
if (someCondition)
NSLog(@"this is wrong!!!");
while(someCondition)
NSLog(@"this is wrong!!!");
}
6> 警告
• 需要添加警告的地方写上warning和注释,在编译的过程中会注意到
示例:(void)goBack {
warning 待完善
}
• 对于过期的方法、类、结构体和枚举等,使用系统自带的deprecated系列和NS_UNAVAILABLE
方法警告。
- 目录格式
1> 根据项目的功能从大块到小块对文件用不同的文件夹进行分装;
2> 按照项目的功能进行分类的,文件夹用中文命名;
3> 按照代码的功能进行分类的,文件夹可以用英文或中文命名;
4> 第三方库和工具单独存放到一个文件夹;
5> 根据情况,小尺寸图片统一放到Assets.xcassets,同样用文件夹分类存放;
6> 其他图片,尤其是大图,要放在boundle里,一般放在“/Resources/图片/”里;
7> 通用的类,根据视图、模型和控制器的分类用不同文件夹分类存放;
8> 具体到某一个小模块,则根据MVC对文件进行分类。 - git代码管理
1> 先更新,再提交;
2> 提交的时候带上自己的名字,干了什么就写什么,不得遗漏;
3> 有重要的提交,要通知一下其他组员;
4> git分支用版本号作为后缀。 - 其他细节
1> 在Runtime+KVC面前成员变量没有公私之分,建议全部使用@property声明属性,“私有变量”的放在.m文件中的extension中声明即可,.h文件中公开的属性应合理使用readonly修饰。使用@property还有个优势,方便内存管理,规避循环引用;
2> 控制器类中的代码尽量不要超过500行,借助继承、多态、封装三大特性和MVC、MVVM思想简化、拆分代码;
3> 避免使用left、right、123等字样进行View控件命名,以免后续的UI修改导致命名冲突;
4> 声明UIView及其子类属性尽量用weak修饰;
5> ARC环境下声明NSArray/NSDictionary/NSString属性,用copy;声明前三者可变子类属性用strong;
6> 拥有相同功能的类封装成父类;
7> control+i 组合键,自动对齐;
8> MJRefresh、AFNetworking在迭代过程中都出现过修改方法名的情况,比较成熟的解决方案是创建桥梁分类,封装常用的方法。如果第三方库出现命名修改,只要修改桥梁分类中的内容即可,不用每个类都去改方法,节省大量时间。这种解耦思想同样适用于NSTimer,能主动解除循环引用。详情见[https://github.com/XiFengLang/JKKit-OC/tree/master/JKKit/4.自释放定时器];
9> 尽量不要在预编译头文件里引入太多文件,尽量精简;
10> 分类(category)根据功能进行分类和命名;
11> 图片命名根据模块(子模块)功能进行命名;
12> 注意对象的内存释放问题,防止循环引用。