头文件
@import AVFoundation; # 标准组件库库头文件,一般为苹果sdk自带的 framework#import DKViewController.h # 非标准库头文件全局宏常量定义全局变量类定义
切记不要 #import
例子
@import AVFoundation;#import "Test.h"#define KTest 0static CGFloat const kALAnimationDelay = 0.1;static NSString *ID = @"cell";@interface MyClass ()@property (nonatomic) NSObject *test;@end
类结构
使用 #pragma mark – xxx 来分类方法
#pragma mark – Getters and Setters # 懒加载#pragma mark - Life Cycle # 实例生命周期#pragma mark - Events # 事件#pragma mark - Public Methods # .h 公开方法#pragma mark - UITableViewDataSource # 系统代理方法#pragma mark - UITableViewDelegate#pragma mark - UITextFieldDelegate#pragma mark - Custom Delegates # 自定义代理(#pragma mark – Private Methods # 私有方法)
Private Methods
正常情况下 ViewController 里面不应该写,能抽掉尽量抽掉
- 不是 delegate 方法的,也不是 event response 方法的,也不是 life cycle 方法的,就是 private method。
- 正常情况下 ViewController 里面是不会存在 private methods 的,这个 private methods 一般是用于日期换算、图片裁剪等的小功能。这种小功能要么把它写成一个 category,要么把它做成一个模块,哪怕这个模块只有一个函数也行。
- ViewController 基本上是大部分业务的载体,本身代码已经相当复杂,所以跟业务关联不大的东西,能不放在 ViewController 里面就不要放。另外一点,这个 private method 的功能这时候只是你用得到,但是将来说不定别的地方也会用到,一开始就独立出来,有利于将来的代码复用。
懒加载
很多开发工程师,初始化属性的位置比较随意,有单独添加一个初始化方法类似 setupView 的,有在 init 初始化的,各种情况都有,导致团队协作的时候代码显得非常乱。
初始化方式不一致,这样做非常有可能破坏了每个方法功能的单一性(每个方法只做一件事)。
@interface CustomObject ()@property (nonatomic, strong) UILabel *label;@end@implementation#pragma mark - getters and setters- (UILabel *)label{if (_label == nil) {_label = [[UILabel alloc] init];_label.text = @"1234";_label.font = [UIFont systemFontOfSize:12];... ...}return _label;}@end#pragma mark - life cycle- (void)viewDidLoad{[super viewDidLoad];[self.view addSubview:self.label];}- (void)viewWillAppear:(BOOL)animated{[super viewWillAppear:animated];self.label.frame = CGRectMake(1, 2, 3, 4);}
空格
使用空格而不是制表符 Tab
不要在工程里使用 Tab 键,使用空格来进行缩进。在 Xcode > Preferences > Text Editing 将 Tab 和自动缩进都设置为 4 个空格。(Google 的标准是使用两个空格来缩进,但这里还是推荐使用 Xcode 默认的设置。)
每个方法或者功能块之间为了结构清晰,应当只空一行。
该空格的地方要加空格,比如每个方法的开头,在 - 和 (return_type) 之间应该有且只有一个空格;写 property 时,严格按照下面的格式。
@interface SomeClass : NSObject@property (noatomic, weak) UIView *aView- (void)someMethod;@end@implementation SomeClass- (void)setAView:(NSInteger )aview {}- (void)someMethod {}@end
方法书写
先不讨论一个方法带很多参数好不好,假设真的有很多参数导致方法名很长,应该用 : 对齐,每个参数一行,以提高可阅读性。
- (id)initWithModel:(IPCModle)modelconnectType:(IPCConnectType)connectTyperesolution:(IPCResolution)resolutionauthName:(NSString *)authNamepassword:(NSString *)passwordmac:(NSString *)macazIp:(NSString *)az_ipazDns:(NSString *)az_dnstoken:(NSString *)tokenemail:(NSString *)emaildelegate:(id)delegate;
反之如果只有两三个参数,就不要这样分行写了,一行解决即可。
- (id)initWithAuthName:(NSString *)authName password:(NSString *)password;
方法调用
函数调用不要分行,统一单行写完,让编译器自动换行即可。特别是有 block 嵌套的时候,分行会非常难看。一般写完代码的时候可以用一个小技巧来格式化代码:选中代码,然后先按 Command + Alt + [,再按 Command + Alt + ]。就是把这一段代码往上移一行,再往下移一行,回到原来的样子,但是会经过 xCode 的排版,也就达到格式化代码的效果。
例如用:
// blocks are easily readable[UIView animateWithDuration:1.0 animations:^{// something} completion:^(BOOL finished) {// something}];
而不是
// colon-aligning makes the block indentation hard to read[UIView animateWithDuration:1.0animations:^{// something}completion:^(BOOL finished) {// something}];
if 语句
表达式大括号和其他大括号(if/else/switch/while 等)总是在同一行语句打开但在新行中关闭。如果没有 else 并且括号内只有一行语句,可以和 if 语句同行,并且不需要括号。
if (user.isHappy) {//Do something} else {//Do something else}if (somethingIsBad) return something;
switch 语句
大括号在 case 语句中并不是必须的,除非编译器强制要求。当一个 case 语句包含多行代码时,大括号应该加上。
switch (condition) {case 1:// ...break;case 2: {// ...// Multi-line example using bracesbreak;}case 3:// ...break;default:// ...break;}
当在 switch 使用枚举类型时,default 是不需要的。例如:
RWTLeftMenuTopItemType menuType = RWTLeftMenuTopItemMain;switch (menuType) {case RWTLeftMenuTopItemMain:// ...break;case RWTLeftMenuTopItemShows:// ...break;case RWTLeftMenuTopItemSchedule:// ...break;}
注释
代码中尽量少注释,让代码能自我描述。不过当需要注释的时候,能需要清楚地解释某个代码块的含义和作用。注释应当保持最新,如果不必要请删除。
点语法
- 点语法是一种很方便封装访问方法调用的方式。当你使用点语法时,通过使用 getter 或 setter 方法,属性仍然被访问或修改。
- 点语法应该总是被用来访问和修改属性,因为它使代码更加简洁。[ ] 符号更偏向于用在其它例子。
例如用
view.backgroundColor = [UIColor orangeColor];
而不是
[view setBackgroundColor:[UIColor orangeColor]];
Init 和 类构造方法
- (instancetype)init{if (self = [super init]) {// ...}return self;}
当类构造方法被使用时,它应该返回类型是 instancetype 而不是 id,这样确保编译器正确地推断结果类型。
@interface Airplane+ (instancetype)airplaneWithTestType:(DKTestType)type;@end
