简介
Object-C 代码风格
代码结构
使用 #pragma mark -
#pragma mark - 生命周期
#pragma mark - 懒加载
#pragma mark - 响应事件
#pragma mark - 代理事件
#pragma mark - 内部方法
#pragma mark - IBActions
换行
if (user.isHappy) {
//Do something
} else {
//Do something else
}
// blocks are easily readable
[UIView animateWithDuration:1.0 animations:^{
// something
} completion:^(BOOL finished) {
// something
}];
注释
仅根据需要写注释,代码更新后注释需保持更新
命名
- 不使用三个字符的前缀
- 命名含义需完整表达
Preferred:
static NSTimeInterval const RWTTutorialViewControllerNavigationFadeAnimationDuration = 0.3;
Not Preferred:
static NSTimeInterval const fadetime = 1.7;
方法命名
方法和命令应该整个项目保持统一,防止混乱,也便于搜索
- 页面界面创建
- (void)setupUI{}
- 服务端获取数据
- (void)fetchXXX{}
- 属性是数组的应该包含其类型
@property (nonatomic, strong) NSArray<ZANContactTagModel *> *userTags;
- cell 设置数据
- (void)setupDataModel:(id)model{}
- 管理类
@interface XXXManager ()
- 单例
+ (instancetype)sharedInstance {}
属性
- 统一使用self.访问属性(实例初始化中除外,使用_xxx)
- 属性关键字使用(nonatomic, strong, readonly, , getter=)顺序,即原子性、读写权限、内存管理语义、getter/getter
Preferred:
@interface RWTTutorial : NSObject
@property (nonatomic, strong, readonly) NSString *tutorialName;
@end
Not Preferred:
@interface RWTTutorial : NSObject {
NSString *tutorialName;
}
读写属性
读写权限不写时默认为 readwrite 。一般可在 .h 里写成 readonly,只对外提供读取,在 .m 的 extension中再设置为 readwrite 可进行写入。
copy 还是strong
- strong一般用于修饰对象类型、字符串和集合类的可变版本,copy一般用于修饰字符串和集合类的不可变版以及block
- 声明属性时,如果不希望它因为源对象(源对象为可变对象时)的改变而改变,则用copy修饰,NSString 、NSArray 、NSDictionary 等不可变对象用 copy 修饰,因为有可能传入一个可变的版本,此时能保证属性值不会受外界影响
- 若用 strong 修饰 NSArray,当数组接收一个可变数组,可变数组若发生变化,被修饰的属性数组也会发生变化,也就是说属性值容易被篡改;若用 copy 修饰 NSMutableArray,当试图修改属性数组里的值时,程序会崩溃,因为数组被复制成了一个不可变的版本
字面量语法
Preferred:
NSArray *names = @[@"Brian", @"Matt", @"Chris", @"Alex", @"Steve", @"Paul"];
NSDictionary *productManagers = @{@"iPhone": @"Kate", @"iPad": @"Kamal", @"Mobile Web": @"Bill"};
NSNumber *shouldUseLiterals = @YES;
NSNumber *buildingStreetNumber = @10018;
Not Preferred:
NSArray *names = [NSArray arrayWithObjects:@"Brian", @"Matt", @"Chris", @"Alex", @"Steve", @"Paul", nil];
NSDictionary *productManagers = [NSDictionary dictionaryWithObjectsAndKeys: @"Kate", @"iPhone", @"Kamal", @"iPad", @"Bill", @"Mobile Web", nil];
NSNumber *shouldUseLiterals = [NSNumber numberWithBool:YES];
NSNumber *buildingStreetNumber = [NSNumber numberWithInteger:10018];
常量
- const编译器有类型检测,所以使用const 代替 #define
- 常量定义作用范围最小化,仅在某个文件中使用的定义在该文件内,其余的统一放在一个文件内
Preferred:
static NSString * const RWTAboutViewControllerCompanyName = @"RayWenderlich.com";
static CGFloat const RWTImageThumbnailHeight = 50.0;
Not Preferred:
#define CompanyName @"RayWenderlich.com"
#define thumbnailHeight 2
枚举
使用NS_ENUM(), `NS_OPTION(),遍历时候无需default
For Example:
typedef NS_ENUM(NSInteger, RWTLeftMenuTopItemType) {
RWTLeftMenuTopItemMain,
RWTLeftMenuTopItemShows,
RWTLeftMenuTopItemSchedule
};
Booleans
仅使用YES
和 NO
, 因为true
和 false
是在CoreFoundation, C or C++ 中使用,条件判读统一使用简写
Preferred:
if (someObject) {}
if (![anotherObject boolValue]) {}
Not Preferred:
if (someObject == nil) {}
if ([anotherObject boolValue] == NO) {}
if (isAwesome == YES) {} // Never do this.
if (isAwesome == true) {} // Never do this.
函数
有退出逻辑的函数,统一在函数体开头判断
Preferred:
- (void)someMethod {
if (![someOther boolValue]) {
return;
}
}
Not Preferred:
- (void)someMethod {
if ([someOther boolValue]) {
//Do something important
}
}
- 函数应该做一件事。做好这件事。只做一件事
- 避免使用输出参数。如果函数必须要修改某种状态,就修改对象的状态
*被调用函数放在执行函数的后面
网友评论