使用现代化的Objective-Cdai'm
代码组织
使用#prama 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
- (IBAction)submitData:(id)sender {}
#pragma mark - Public
- (void)publicMethod {}
#pragma mark - Private
- (void)privateMethod {}
#pragma mark - Protocol conformance
#pragma mark - UITextFieldDelegate
#pragma mark - UITableViewDataSource
#pragma mark - UITableViewDelegate
点语法
应该 始终 使用点语法来访问或者修改属性;访问其他实例时首选括号。
//good
view.backgroundColor = [UIColor orangeColor];
[UIApplication sharedApplication].delegate;
//bad
[view setBackgroundColor:[UIColor orangeColor]];
UIApplication.sharedApplication.delegate;
间距
- 一个缩进4 个空格,不要使用制表符。
- 方法的大括号和其他的大括号(if/else/switch/while等等)始终和声明在同一行开始,在新的一行结束。
//good
if (user.isHappy) {
// Do something
}else {
// Do something else
}
- 方法之间空一行。
|- (void)method1;
//black line
|- (void)method2;
条件判断
总是使用大括号!
//good
if (!error) {
return success;
}
//bad
if (!error)
return success;
三目运算
单一条件判断优先使用,复杂情况if判断。
//good
result = a > b ? x : y;
//bad
result = a > b ? x = c > d ? c : d : y;
错误处理
当调用包含错误参数的方法时,针对返回值判断,而非错误变量。
//good
NSError *error;
if (![self trySomethingWithError:&error]) {
// 处理错误
}
//bad
NSError *error;
[self trySomethingWithError:&error];
if (error) {
// 处理错误
}
方法
方法签名中,在-、+符号后空格;方法片段之间空格。
//good
- (void)setExampleText:(NSString *)text image:(UIImage *)image;
//bad
-(void)setExampleText:(NSString *)text image:(UIImage *)image;
变量
- 变量名应该尽可能命名为描述性的。
- 除了 for()循环外,避免使用单字母的变量名。
- 带*的,写成 NSString *text。
- 尽量使用属性而不是成员变量。
//good
@interface NYTSection: NSObject
@property (nonatomic) NSString *headline;
@end
//bad
@interface NYTSection : NSObject {
NSString *headline;
}
- 带变量限定符时,变量限定符位于*和变量名之间。如:NSString * __weak text。
命名
- 遵守苹果命名约定。
- 清晰可描述。
- 变量、属性、方法首字母小写。
//good
UIButton *settingsButton;
//bad
UIButton *setBut;
- 常量带类名前缀,并大写。
//good
static const NSTimeInterval NYTArticleViewControllerNavigationFadeAnimationDuration = 0.3;
//bad
static const NSTimeInterval fadetime = 1.7;
注释
一般不需要。保证变量名&方法名的可读性!除非特殊或复杂逻辑。
字面量
创建NSString, NSDictionary, NSArray和 NSNumber类的不可变实例时,都应该使用字面量。
//good
NSArray *names = @[@"Brian", @"Matt", @"Chris", @"Alex", @"Steve", @"Paul"];
NSDictionary *productManagers = @{@"iPhone" : @"Kate", @"iPad" : @"Kamal", @"Mobile Web" : @"Bill"};
NSNumber *shouldUseLiterals = @YES;
NSNumber *buildingZIPCode = @10018;
//bad
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 *buildingZIPCode = [NSNumber numberWithInteger:10018];
CGRect函数
当访问一个 CGRect的 x, y, width, height时,应该使用CGGeometry函数代替直接访问结构体成员。
//good
CGRect frame = self.view.frame;
CGFloat x = CGRectGetMinX(frame);
CGFloat y = CGRectGetMinY(frame);
CGFloat width = CGRectGetWidth(frame);
CGFloat height = CGRectGetHeight(frame);
//bad
CGRect frame = self.view.frame;
CGFloat x = frame.origin.x;
CGFloat y = frame.origin.y;
CGFloat width = frame.size.width;
CGFloat height = frame.size.height;
常量 VS #define
常量首选内联字符串字面量或数字,因为常量可以轻易重用并且可以快速改变而不需要查找和替换。常量应该声明为 static常量而不是 #define,除非非常明确地要当做宏来使用。
//good
static NSString * const NYTAboutViewControllerCompanyName = @"The New York Times Company";
static const CGFloat NYTImageThumbnailHeight = 50.0;
//bad
#define CompanyName @"The New York Times Company"
#define thumbnailHeight 2
枚举
使用 NS_ENUM()来定义。
typedef NS_ENUM(NSInteger, NYTAdRequestState) {
NYTAdRequestStateInactive,
NYTAdRequestStateLoading
};
单例
+ (instancetype)sharedInstance {
static id sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}
Xcode工程分组
物理文件结构应该保持和 Xcode 项目文件结构同步。