代码组织
在函数分组和protocol/delegate实现中使用#pragma mark -来分类方法,要遵循以下一般结构:
#pragma mark - Lifecycle
- (instancetype)init {}
- (void)dealloc {}
- (void)viewDidLoad {}
- (void)viewWillAppear:(BOOL)animated {}
- (void)didReceiveMemoryWarning {}
#pragma mark - Custom Accessors
- (void)setCustomProperty:(id)value {}
- (id)customProperty {}
#pragma mark - IBActions/Event Response
- (IBAction)submitData:(id)sender {}
- (void)someButtonDidPressed:(UIButton*)button
#pragma mark - Protocol conformance
#pragma mark - UITextFieldDelegate
#pragma mark - UITableViewDataSource
#pragma mark - UITableViewDelegate
#pragma mark - Public
- (void)publicMethod {}
#pragma mark - Private
- (void)privateMethod {}
#pragma mark - NSCopying
- (id)copyWithZone:(NSZone *)zone {}
#pragma mark - NSObject
- (NSString *)description {}
回车
方法大括号和其他大括号(if/else/switch/while 等.)总是在同一行语句打开但在新行中关闭。
应该:
if (user.isHappy) {
//Do something
} else {
//Do something else
}
不应该:
if (user.isHappy)
{
//Do something
}
else {
//Do something else
}
在方法之间应该有且只有一行,这样有利于在视觉上更清晰和更易于组织。在方法内的空白应该分离功能,但通常都抽离出来成为一个新方法。
应该避免以冒号对齐的方式来调用方法。因为有时方法签名可能有3个以上的冒号和冒号对齐会使代码更加易读。
应该:
// 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.0
animations:^{
// something
}
completion:^(BOOL finished) {
// something
}];
注释
当需要注释时,注释应该用来解释这段特殊代码为什么要这样做。任何被使用的注释都必须保持最新或被删除。
/**
新车上市
@param minprice 最低价格
@param maxprice 最高价格
@param page 页数
@param success 成功
@param failure 失败
*/
- (void)getNewCarWithMinprice:(NSString *)minprice
maxprice:(NSString *)maxprice
page:(int)page
success:(EventHandler)success
failure:(EventHandler)failure;
命名
/**
声明变量 满足驼峰(对象类型缩写+功能 如下)
*/
@property (nonatomic, strong) UIButton * btnLogin;
@property (nonatomic, strong) UILabel * lbDes;
@property (nonatomic, strong) UITableView * tbFeed;
@property (nonatomic, strong) UITextField * tfUserName;
@property (nonatomic, strong) UITextView * tvDes;
下划线
当使用属性时,实例变量应该使用self.来访问和改变。这就意味着所有属性将会视觉效果不同,因为它们前面都有self.。
但有一个特例:在初始化方法里,实例变量(例如,_variableName)应该直接被使用来避免getters/setters潜在的副作用。
局部变量不应该包含下划线。
方法
在方法签名中,应该在方法类型(-/+ 符号)之后有一个空格。在方法各个段之间应该也有一个空格(符合Apple的风格)。在参数之前应该包含一个具有描述性的关键字来描述参数。
/**
方法声明 满足驼峰 (方法功能+参数说明以及参数)
*/
- (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)showCarWithType:(CarType)type carYear:(Caryear)carYear{}
常量
常量是容易重复被使用和无需通过查找和代替就能快速修改值。常量应该使用static来声明而不是使用#define,除非显式地使用宏。
应该:
static NSString * const XYAboutViewControllerCompanyName = @"RayWenderlich.com";
static CGFloat const XYImageThumbnailHeight = 50.0;
不应该:
#define CompanyName @"RayWenderlich.com"
#define thumbnailHeight 2
枚举类型
当使用enum时,推荐使用新的固定基本类型规格,因为它有更强的类型检查和代码补全。现在SDK有一个宏NS_ENUM()来帮助和鼓励你使用固定的基本类型。
例如:
typedef NS_ENUM(NSInteger,XYCommentViewStatus) {
XYCommentViewStatus_None ,//
XYCommentViewStatus_KeyBoard,//键盘输入
XYCommentViewStatus_Image,//图片选择
XYCommentViewStatus_Position //位置选择
};
不应该:
enum GlobalConstants {
kMaxPinSize = 5,
kMaxPinCount = 500,
};
Init方法 / 类构造方法
Init方法应该遵循Apple生成代码模板的命名规则。返回类型应该使用instancetype
而不是id
- (instancetype)init {
self = [super init];
if (self) {
// ...
}
return self;
}
+ (instancetype)airplaneWithType:(int)type;
单例模式
单例对象应该使用线程安全模式来创建共享实例。
+ (instancetype)sharedInstance {
static id sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}
Xcode工程
物理文件应该与Xcode工程文件保持同步来避免文件扩张。任何Xcode分组的创建应该在文件系统的文件体现。代码不仅是根据类型来分组,而且还可以根据功能来分组,这样代码更加清晰。