Language 语言
使用美式英语
Preferred:
UIColor *myColor = [UIColor whiteColor];
Not Preferred:
1.UIColor *myColour = [UIColor whiteColor];//Colour 英式英语
2.UIColor *myYanSe = [UIColor whiteColor];//YanSe
...
Code Organization 代码结构
使用 #pragma mark - 去分类 methods组、protocol/delegate...
#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
#pragma mark - NSCopying
- (id)copyWithZone:(NSZone *)zone {}
#pragma mark - NSObject
- (NSString *)description {}
Spacingkon 空格
方法括号和其他括号(if / else / switch / while等)始终在语句相同的行上打开,但在新行上关闭。
Preferred:
if (user.isHappy) {
//Do something
} else {
//Do something else
}
Not Preferred:
if (user.isHappy)
{
//Do something
}
else
{
//Do something else
}
Preferred:
// blocks are easily readable
[UIView animateWithDuration:1.0 animations:^{
// something
} completion:^(BOOL finished) {
// something
}];
Not Preferred:
// colon-aligning makes the block indentation hard to read
[UIView animateWithDuration:1.0
animations:^{
// something
}
completion:^(BOOL finished) {
// something
}];
Comments 注释
1.注释用于特定代码片段起得作用
2.使用的任何注释都必须保持最新或刪除。
3.尽量避免使用大篇幅的注释块,代码应该是尽可能的自我说明与记录,只需要是间歇性的几行解释
Naming 命名
驼峰法
UILabel *myNameLabl = [UILabel new];
冗長的描述性方法和变量名称都很好,不要为了简单而失去可读性
Preferred:
UIButton *settingsButton;
Not Preferred:
UIButton *setBut;
对于类名和常量,应始终三个字母的前缀(apple申明过 保留所有两个字母前缀的使用权,如果哪天apple使用了,你的代码就凉了);对于Core Data实体名称可以省略前缀。
eg:假设简书前缀是 JST(JianShuTeam),不应该是JS
Preferred:
static NSTimeInterval const JSTTutorialViewControllerNavigationFadeAnimationDuration = 0.3;
Not Preferred:
static NSTimeInterval const
JSTutorialViewControllerNavigationFadeAnimationDuration = 0.3;
static NSTimeInterval const fadetime = 1.7;
属性开头应是小写字母,类名开头应是大写;并且符合驼峰法
Preferred:
@property (strong, nonatomic) NSString *descriptiveVariableName;
interface JSTManangeCenter :NSObject
Underscores 下划线
访问属性时应尽可能使用self. 访问,而不是使用下划线访问实例变量
但是:內部初始化器,应该直接使用支持实例变量(即_variableName)來避免getter / setter的任何潜在副作用。
局部变量不应该包含下划线
Methods 方法
在方法签名中,方法类型( - / +符号)后面应该有一个空格。
方法段之间应该有一个空格(匹配Apple的样式)。
始终包含一个关键字,并在描述参数的参数之前用单词描述。
不使用 and或者少使用
Preferred:
- (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;
Not Preferred:
-(void)setT:(NSString *)text i:(UIImage *)image;
- (void)sendAction:(SEL)aSelector :(id)anObject :(BOOL)flag;
- (id)taggedView:(NSInteger)tag;
- (instancetype)initWithWidth:(CGFloat)width andHeight:(CGFloat)height;
- (instancetype)initWith:(int)width and:(int)height; // Never do this.
Variables 变量
变量应该尽可能的描述;
避免使用单个单词
应尽可能使用私有属性代替实例变量。尽管使用实例变量是一种有效的处理方式,但通过统一属性,我們的代码將更加一致。
Preferred:
@interface RWTTutorial : NSObject
@property (strong, nonatomic) NSString *tutorialName;
@end
Not Preferred:
@interface RWTTutorial : NSObject {
NSString *tutorialName;
}
指针*属于变量
Preferred:
NSString *text
Not Preferred:
not NSString* text or NSString * text
Property Attributes 属性 前缀
像weak、strong、nonatomic 这种Property Attributes,应该明确列出,并在阅读代码时帮助新程序员。顺序一般是强弱引用然后是原子性。
Preferred:
@property (weak, nonatomic) IBOutlet UIView *containerView;
@property (strong, nonatomic) NSString *tutorialName;
Not Preferred:
@property (nonatomic, weak) IBOutlet UIView *containerView;
@property (nonatomic) NSString *tutorialName;
具有可变对应物的属性(NSString.NSArray)应该使用Copy 而不是Strong
Preferred:
@property (copy, nonatomic) NSString *tutorialName;
Not Preferred:
@property (strong, nonatomic) NSString *tutorialName;
Dot-Notation Syntax 点号语法
点号(.)语法应始终用于读写属性,因为它使代码更简洁。在所有其他情况下,首选括号([])。
Preferred:
NSInteger arrayCount = [self.array count];
view.backgroundColor = [UIColor orangeColor];
[UIApplication sharedApplication].delegate;
Not Preferred:
NSInteger arrayCount = self.array.count;
[view setBackgroundColor:[UIColor orangeColor]];
UIApplication.sharedApplication.delegate;
Literals 字面量
每当创建NSString,NSDictionary,NSArray和NSNumber这些对象的不可变实例时,都应使用字面量。特別注意nil值不能传给NSArray和NSDictionary,会导致崩溃。
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];
Constants 常量
除非明确用作宏,否則应将常量生命为静态常量而不是#defines。
Preferred:
static NSString * const RWTAboutViewControllerCompanyName = @"RayWenderlich.com";
static CGFloat const RWTImageThumbnailHeight = 50.0;
Not Preferred:
#define CompanyName @"RayWenderlich.com"
#define thumbnailHeight 2
Enumerated Types 枚举类型
使用新的NS_ENUM 去声明,并且加上工程前缀
Preferred:
typedef NS_ENUM(NSInteger, JSTLeftMenuTopItemType) {
JSTLeftMenuTopItemMain,
JSTLeftMenuTopItemShows,
JSTLeftMenuTopItemSchedule
};
typedef NS_ENUM(NSInteger, JSTGlobalConstants) {
JSTPinSizeMin = 1,
JSTPinSizeMax = 5,
JSTPinCountMin = 100,
JSTPinCountMax = 500,
};
Not Preferred:
enum GlobalConstants {
kMaxPinSize = 5,
kMaxPinCount = 500,
};
Case Statements Case语句
除非由编译器强制执行,否则case语句不需要括號。 当某个case包含多行语句时,应添加大括号;多个条件执行相同语句时,去掉break 会有 fall-through贯穿效果
switch (condition) {
case 1:
// ...
break;
case 2: {
// ...
// Multi-line example using braces
break;
}
case 3:
case 4:
case 5:
// dong something
break;
default:
// ...
break;
}
使用枚举类型作为开关时,不需要“ default”
JSTLeftMenuTopItemType menuType = JSTLeftMenuTopItemMain;
switch (menuType) {
case JSTLeftMenuTopItemMain:
// ...
break;
case JSTLeftMenuTopItemShows:
// ...
break;
case JSTLeftMenuTopItemSchedule:
// ...
break;
}
Private Properties 私有属性
私有属性应该申明在类扩展(匿名分类)中的.m文件中
For Example:
@interface RWTDetailViewController ()
@property (strong, nonatomic) GADBannerView *googleAdView;
@property (strong, nonatomic) ADBannerView *iAdView;
@property (strong, nonatomic) UIWebView *adXWebView;
@end
Booleans 布尔值
OC使用 YES和NO,因此true和false应该用于CoreFoundation,C,C++
由于nil解析为NO,因此无需在条件下进行比较
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.
Conditionals 條件語句
有条件的主体应该总是使用大括号,即使条件主体可以没有大括号(例如,它只是一行)来防止错误。
Preferred:
if (!error) {
return success;
}
Not Preferred:
if (!error)
return success;
or
if (!error) return success;
Ternary Operator 三元运算符
三元运算符?:只应在增加清晰度或代码整洁度时使用。 一个条件通常都应该被评估。 评估多个条件通常更容易理解为if语句,或重构为实例变量。 通常,三元运算符的最佳用途是在赋值变量和决定使用哪个值期间。
应该将非布尔变量与某些内容进行比较,并添加括号以提高可读性。 如果要比较的变量是布尔类型,则不需要括号。
Preferred:
NSInteger value = 5;
result = (value != 0) ? x : y;
BOOL isHorizontal = YES;
result = isHorizontal ? x : y;
Not Preferred:
result = a > b ? x = c > d ? c : d : y;
Init Methods 初始化
Init方法应遵循Apple生成的代码模板提供的约定。还应使用返回类型“instancetype”而不是“id”。
- (instancetype)init {
self = [super init];
if (self) {
// ...
}
return self;
}
Class Constructor Methods 类构造方法
在使用类构造函数方法的地方,这些方法应始终返回'instancetype'类型而不是'id'。 这可确保编译器正确推断结果类型。
@interface Airplane
+ (instancetype)airplaneWithType:(RWTAirplaneType)type;
@end
CGRect Functions CGRect功能
访问CGRect的x,y,width或height时,始终使用CGGeometry函数而不是直接的struct member访问。 来自Apple的CGGeometry参考:
Preferred:
CGRect frame = self.view.frame;
CGFloat x = CGRectGetMinX(frame);
CGFloat y = CGRectGetMinY(frame);
CGFloat width = CGRectGetWidth(frame);
CGFloat height = CGRectGetHeight(frame);
CGRect frame = CGRectMake(0.0, 0.0, width, height);
Not Preferred:
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;
CGRect frame = (CGRect){ .origin = CGPointZero, .size = frame.size };
Golden Path 黄金路径
使用条件编码时,代码的左边距应为“黄金”或“快乐”路径。 也就是说,不要嵌套if语句。 多个return语句都可以。
Preferred:
- (void)someMethod {
if (![someOther boolValue]) {
return;
}
//Do something important
}
Not Preferred:
- (void)someMethod {
if ([someOther boolValue]) {
//Do something important
}
}
Error handling 错误处理
当方法通过引用返回错误参数时,请打开返回的值,而不是错误变量。
在成功的情况下,Apple的某些API会将垃圾值写入错误参数(如果为非NULL),因此启用错误可能会导致错误否定(并随后崩溃)。
Preferred:
NSError *error;
if (![self trySomethingWithError:&error]) {
// Handle Error
}
Not Preferred:
NSError *error;
[self trySomethingWithError:&error];
if (error) {
// Handle Error
}
Singletons 单例
Singleton对象应使用线程安全模式来创建其共享实例。
+ (instancetype)sharedInstance {
static id sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}
Line Breaks 换行
换行注重于可读性
For example:
self.productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:productIdentifiers];
Preferred:
self.productsRequest = [[SKProductsRequest alloc]
initWithProductIdentifiers:productIdentifiers];
Smiley Face 笑脸
笑脸是某些coder非常突出的风格特征! 拥有正确的微笑非常重要,这标志着编码主题的巨大快乐和兴奋。 使用末端方括号是因为它代表了能够使用ascii艺术捕获的最大微笑。 如果使用末端括号,则表示半心半意的微笑,因此不是优选的。
Preferred:
:]
Not Preferred:
:)
Xcode project
物理文件应与Xcode项目文件保持同步,以避免文件蔓延。 创建的任何Xcode组都应该由文件系统中的文件夹反映出来。 代码不仅应按类型分组,还应按功能分组,以便更清晰。
如果这篇文章对您有用,烦请点个赞,这是对小弟最大的支持,谢谢