OC代码规范

命名

Preferred :

UIColor *myColor = [UIColor whiteColor];

Not Preferred :

UIColor *myColour = [UIColor whiteColor];

代码组织

使用#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

- (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 {}

#pragma mark -  lazy

空格

  • 使用2个空格不要使用Tab键
  • 方法和其他后的大括弧在第一行开始在新的一行结束。
    Preferred:
if (user.isHappy) {
  //Do something
} else {
  //Do something else
}

Not Preferred:

if (user.isHappy)
{
    //Do something
}
else {
    //Do something else
}
  • 在方法中的参数中间添加一个空格方便阅读。
  • 优先使用自动生成,但是如果需要的话可以在实现文件中添加@ synthesize 和 @dynamic。
  • 调用方法时尽量避免方法中冒号对齐。当方法中包含3个以上的参数,使用冒号对齐会增加方法的可读性。但是,当方法中包含block时Xcode 的自动对齐会让代码看起来不容易分辨。
    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
                 }];

注释

所有的注释必须保持最新或者删除,避免块注释。

命名

尽量保持苹果的命名方式,长的,描述性和变量名都很好。
Preferred:

UIButton *settingsButton;

Not Preferred:

UIButton *setBut;

对于类名和常量名一般使用三字母前缀,在coreData 实体名称可以省略。常量一般遵循驼峰命名方式,使用相关类名最为前缀。
Preferred:

static NSTimeInterval const RWTTutorialViewControllerNavigationFadeAnimationDuration = 0.3;

Not Preferred:

static NSTimeInterval const fadetime = 1.7;

属性命名应该遵循首字母小写的驼峰原则。尽量使用自动生成而非手动。
Preferred:

@property (strong, nonatomic) NSString *descriptiveVariableName;

Not Preferred:

id varnm;

下划线

在初始化的时候,实例变量使用下划线。局部变量不要使用下划线。

方法

在(+/-)符号后添加一个空格,关键词应该对参数有简单的描述。
关键字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.

变量

应该使用可描述的变量名称。单字符变量名除了在for循环中使用其他情况不宜使用。
*号应该跟在变量前,NSString text not NSString text;
尽量使用私有属性代替实例变量。
Preferred:

@interface RWTTutorial : NSObject
@property (strong, nonatomic) NSString *tutorialName;
@end

Not Preferred:

@interface RWTTutorial : NSObject {
  NSString *tutorialName;
}

属性

Preferred:

@property (weak, nonatomic) IBOutlet UIView *containerView;
@property (strong, nonatomic) NSString *tutorialName;

Not Preferred:

@property (nonatomic, weak) IBOutlet UIView *containerView;
@property (nonatomic) NSString *tutorialName;

字符串属性推荐使用copy不建议使用strong。
Preferred:

@property (copy, nonatomic) NSString *tutorialName;

Not Preferred:

@property (strong, nonatomic) NSString *tutorialName;

点语法

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;

字面量

NSString, NSDictionary, NSArray, and NSNumber中尽量使用不可变的值。不要在NSArray 和NSDictionary中添加nil值会引起崩溃。
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];

常量

常量应该是静态的常量,不应该是#define 除非作为宏使用。
Perferred:

static NSString * const RWTAboutViewControllerCompanyName = @"RayWenderlich.com";
static CGFloat const RWTImageThumbnailHeight = 50.0;

Not Perferred:

#define CompanyName @"RayWenderlich.com"#define thumbnailHeight 2

枚举类型

For Example:

typedef NS_ENUM(NSInteger, RWTLeftMenuTopItemType) {
  RWTLeftMenuTopItemMain,
  RWTLeftMenuTopItemShows,
  RWTLeftMenuTopItemSchedule
};

你可以明确值的分配

typedef NS_ENUM(NSInteger, RWTGlobalConstants) {
  RWTPinSizeMin = 1,
  RWTPinSizeMax = 5,
  RWTPinCountMin = 100,
  RWTPinCountMax = 500,
};

Not Preferred:

enum GlobalConstants {
  kMaxPinSize = 5,
  kMaxPinCount = 500,
};

case 状态

当在switch中使用枚举类型,default是不需要的。

RWTLeftMenuTopItemType menuType = RWTLeftMenuTopItemMain;

switch (menuType) {
  case RWTLeftMenuTopItemMain:
    // ...
    break;
  case RWTLeftMenuTopItemShows:
    // ...
    break;
  case RWTLeftMenuTopItemSchedule:
    // ...
    break;
}

私有属性

私有属性应该在类的实现文件中的类扩展(匿名分类)中声明,命名分类(比如RWTPrivate或private)应该从不使用除非是扩展其他类。匿名分类应该通过使用<headerfile>+Private.h文件的命名规则暴露给测试。

@interface RWTDetailViewController ()
@property (strong, nonatomic) GADBannerView *googleAdView;
@property (strong, nonatomic) ADBannerView *iAdView;
@property (strong, nonatomic) UIWebView *adXWebView;
@end

布尔类型

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.

如果BOOL属性的名字是一个形容词,属性就能忽略"is"前缀,但要指定get访问器的惯用名称。

@property (assign, getter=isEditable) BOOL editable;

条件语句

  • 后面要加大括号
    Preferred:
if (!error) {
  return success;
}

Not Preferred:

if (!error)
  return success;

or

if (!error)  return success;

三目运算符

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;

初始化方法

  • 返回类型是instancetype不是返回id。确保编译器正确判断推断结果。
- (instancetype)init {
  self = [super init];
  if (self) {
    // ...
  }
  return self;
}

类构造方法

要求同上

@interface Airplane
+ (instancetype)airplaneWithType:(RWTAirplaneType)type;
@end

CGRect 方法

  • 访问x,y,width或者height时使用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

Preferred:

- (void)someMethod {
  if (![someOther boolValue]) {
    return;
  }

  //Do something important
}

Not Preferred:

- (void)someMethod {
  if ([someOther boolValue]) {
    //Do something important
  }
}

错误处理

判断返回值而不是错误变量。
Preferred:

NSError *error;
if (![self trySomethingWithError:&error]) {
  // Handle Error
}

Not Preferred:

NSError *error;
[self trySomethingWithError:&error];
if (error) {
  // Handle Error
}

单例模式

  • 使用线程安全方式创建实例。
+ (instancetype)sharedInstance {
  static id sharedInstance = nil;

  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    sharedInstance = [[self alloc] init];
  });

  return sharedInstance;
}

换行符

一行代码太长的话可以使用换行符,换成两行。

self.productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:productIdentifiers];

down

self.productsRequest = [[SKProductsRequest alloc]     
    initWithProductIdentifiers:productIdentifiers];

  • 少用++ -- 运算符
  • 规范只是建议不要拘泥
  • 对于文章的大部分内容还是认同的,但是对于方法名(+/-)符号后添加空格,就个人而言感觉意义并不大。

参考文章

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,236评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,867评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,715评论 0 340
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,899评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,895评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,733评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,085评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,722评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,025评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,696评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,816评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,447评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,057评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,254评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,204评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,561评论 2 343

推荐阅读更多精彩内容

  • Objective-C Coding Guidelines In Chinese Objective-C编码规范,...
    爨乡的云阅读 491评论 0 0
  • 示例 下面是一个示例头文件,演示了@interface声明的正确注释和间隔 一个示例源文件,演示了一个接口的@ i...
    我是Damo阅读 1,977评论 2 5
  • 转载自:『博爱』 Objective-C-Coding-Guidelines-In-Chinese 概要 Obje...
    王_尧阅读 1,188评论 0 2
  • 1.属性命名 // 属性命名:小驼峰+类型后缀 变量尽量以描述性的方式来命名。单个字符的变量命名应该尽量避免,除了...
    luxing123阅读 314评论 0 0
  • OC代码规范 一、代码格式 1.1、使用空格而不是制表符Tab 不要在工程里使用 Tab 键,使用空格来进行缩进。...
    whocare_阅读 2,022评论 0 3