Objective-C Style Guide 编码规范

介绍

为什么会有这篇文档?

Objective-C编码规范的整理,整理的还不是很完整,还有待完善。

目录

代码组织

在.m文件中使用#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 {}

命名

命名必须使用驼峰命名法

不要担心方法名或变量名过长,推荐使用描述性的方法或命名。

类名第一个字母必须大写

推荐:

UIButton *settingsButton;

UILabel *sharedProductCountLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 40)

不推荐:

UIButton *setBut;
NSNotification *noti;
UILabel *lab;
- (void)setBg:(UIColor *)color;
- (void)destSel:(NSString *)str;

常量应该使用驼峰式命名规则,所有的单词首字母大写和加上与类名有关的前缀,属性则不一样。

推荐:

static NSTimeInterval const RWTTutorialViewControllerNavigationFadeAnimationDuration = 0.3;

不推荐:

static NSTimeInterval const fadetime = 1.7;

属性的首单词的首字母应该小写。属性尽量使用auto-synthesis,最好不要手动编写@synthesize语句。

推荐:

@property (strong, nonatomic) NSString *descriptiveVariableName;

不推荐:

id varnm;

注释

当需要注释时,注释应该用来解释这段特殊代码为什么要这样做。任何被使用的注释都必须保持最新或被删除。

属性注释必须使用三个斜杠,这样子变量就会有代码提示。

/// 商品Id
@property (assign, nonatomic) NSInteger productId;

/// 下载地址
@property (copy, nonatomic) NSString *downloadUrl;

在Xcode 8中,方法使用系统的快捷键 Option(Alt) + Command + /,会自动类似以下的格式。

/**
 Description

 @param text text description
 @param image image description
 */
- (void)setExampleText:(NSString *)text image:(UIImage *)image;

空格

  • 方法的大括号和其他的大括号(if/else/switch/while 等等)总是在同一行语句打开,但在新行中关闭。

推荐:

if (user.isHappy) {
  //Do something
} else {
  //Do something else
}

不推荐:

if (user.isHappy)
{
    //Do something
}
else {
    //Do something else
}
  • 方法之间应该正好空一行,这有助于视觉清晰度和代码组织性。在方法中的在方法内的空白应该分离功能,但通常都抽离出来成为一个新方法。
  • 优先使用auto-synthesis。但如果有必要,@synthesize@dynamic应该在实现中每个都声明新的一行。

  • 应该避免以冒号对齐的方式来调用方法。因为有时方法签名可能有3个以上的冒号和冒号对齐会使代码更加易读。请不要这样做,尽管冒号对齐的方法包含代码块,因为Xcode的对齐方式令它难以辨认。

推荐:

NSInteger index = 1;
switch (index) {
   case 1:

       // Do something
       break;

   case 2:

       // Do something
       break;

   case 3: {

       // something
       break;
   }

   default:
       break;
}
// 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
                 }];

方法

在写方法的时候,注意在方法类型(-/+ 符号)之后有一个空格。在方法各个段之间应该也有一个空格(符合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)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.

变量

变量尽量以描述性的方式来命名。

星号表示变量是指针。例如, NSString *text 不应该用 NSString* textNSString * text

推荐:

@interface RWTTutorial : NSObject

@property (copy, nonatomic) NSString *tutorialName;

@end

不推荐:

@interface RWTTutorial : NSObject {
  NSString *tutorialName;
}

属性特性

属性特性使用注意:

推荐:

/// 不可变的正常用copy,如NSString, NSArray, NSDictionary
@property (copy, nonatomic) NSString *tutorialName;

/// 可变的必须要用strong,
@property (strong, nonatomic) NSMutableString *tutorialName;

/// IBOutlet正常使用weak
@property (weak, nonatomic) IBOutlet UIView *containerView;

/// 代码块也应该使用copy
@property (copy, nonatomic) void (^handleAction)(void);

不推荐:

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

点语法

点语法是一种很方便封装访问方法调用的方式。当你使用点语法时,通过使用getter或setter方法,属性仍然被访问或修改。

使用点语法用来访问和修改属性,这样子会使代码更加简洁。

推荐:

NSInteger arrayCount = [self.array count];
view.backgroundColor = [UIColor orangeColor];
[UIApplication sharedApplication].delegate;

不推荐:

NSInteger arrayCount = self.array.count;
[view setBackgroundColor:[UIColor orangeColor]];
UIApplication.sharedApplication.delegate;

常量

在定义一些常量的话,应该使用static来定义,不应该使用#define,除非显式地使用宏。

推荐:

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

static CGFloat const RWTImageThumbnailHeight = 50.0;

不推荐:

#define CompanyName @"RayWenderlich.com"

#define thumbnailHeight 2

枚举类型

例如:

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

不推荐:

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

单例模式

单例对象应该使用线程安全模式来创建共享实例。

+ (instancetype)sharedInstance {
  static id sharedInstance = nil;

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

  return sharedInstance;
}

导入

如果有一个以上的 import 语句,就对这些语句进行分组。每个分组的注释是可选的。
注:对于模块使用 @import语法。

// Frameworks
@import QuartzCore;

// Models
#import "NYTUser.h"

// Views
#import "NYTButton.h"
#import "NYTUserView.h"

本文参考:

猜你喜欢

转载自blog.csdn.net/h1101723183/article/details/65633661