iOS代碼規(guī)范

Language 語言

使用美式英語

Preferred:
UIColor *myColor = [UIColor whiteColor];
Not Preferred:
1.UIColor *myColour = [UIColor whiteColor];//Colour 英式英語
2.UIColor *myYanSe = [UIColor whiteColor];//YanSe
...

Code Organization 代碼結(jié)構(gòu)

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

方法括號(hào)和其他括號(hào)(if / else / switch / while等)始終在語句相同的行上打開,但在新行上關(guān)閉。

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.盡量避免使用大篇幅的注釋塊,代碼應(yīng)該是盡可能的自我說明與記錄,只需要是間歇性的幾行解釋

Naming 命名

駝峰法
UILabel *myNameLabl = [UILabel new];

冗長的描述性方法和變量名稱都很好,不要為了簡單而失去可讀性
Preferred:
UIButton *settingsButton;

Not Preferred:
UIButton *setBut;

對(duì)于類名和常量,應(yīng)始終三個(gè)字母的前綴(apple申明過 保留所有兩個(gè)字母前綴的使用權(quán),如果哪天apple使用了,你的代碼就涼了);對(duì)于Core Data實(shí)體名稱可以省略前綴。
eg:假設(shè)簡書前綴是 JST(JianShuTeam),不應(yīng)該是JS
Preferred:
static NSTimeInterval const JSTTutorialViewControllerNavigationFadeAnimationDuration = 0.3;

Not Preferred:
static NSTimeInterval const 
 JSTutorialViewControllerNavigationFadeAnimationDuration = 0.3;
static NSTimeInterval const fadetime = 1.7;

屬性開頭應(yīng)是小寫字母,類名開頭應(yīng)是大寫;并且符合駝峰法
Preferred:
@property (strong, nonatomic) NSString *descriptiveVariableName;
interface JSTManangeCenter :NSObject

Underscores 下劃線

訪問屬性時(shí)應(yīng)盡可能使用self. 訪問,而不是使用下劃線訪問實(shí)例變量
但是:內(nèi)部初始化器,應(yīng)該直接使用支持實(shí)例變量(即_variableName)來避免getter / setter的任何潛在副作用。
局部變量不應(yīng)該包含下劃線

Methods 方法

在方法簽名中,方法類型( - / +符號(hào))后面應(yīng)該有一個(gè)空格。
方法段之間應(yīng)該有一個(gè)空格(匹配Apple的樣式)。
始終包含一個(gè)關(guān)鍵字,并在描述參數(shù)的參數(shù)之前用單詞描述。
不使用 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 變量

變量應(yīng)該盡可能的描述;
避免使用單個(gè)單詞

應(yīng)盡可能使用私有屬性代替實(shí)例變量。盡管使用實(shí)例變量是一種有效的處理方式,但通過統(tǒng)一屬性,我們的代碼將更加一致。

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,應(yīng)該明確列出,并在閱讀代碼時(shí)幫助新程序員。順序一般是強(qiáng)弱引用然后是原子性。

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

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

具有可變對(duì)應(yīng)物的屬性(NSString.NSArray)應(yīng)該使用Copy 而不是Strong

Preferred:
@property (copy, nonatomic) NSString *tutorialName;

Not Preferred:
@property (strong, nonatomic) NSString *tutorialName;

Dot-Notation Syntax 點(diǎn)號(hào)語法

點(diǎn)號(hào)(.)語法應(yīng)始終用于讀寫屬性,因?yàn)樗勾a更簡潔。在所有其他情況下,首選括號(hào)([])。

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 字面量

每當(dāng)創(chuàng)建NSString,NSDictionary,NSArray和NSNumber這些對(duì)象的不可變實(shí)例時(shí),都應(yīng)使用字面量。特別注意nil值不能傳給NSArray和NSDictionary,會(huì)導(dǎo)致崩潰。

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 常量

除非明確用作宏,否則應(yīng)將常量生命為靜態(tài)常量而不是#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語句

除非由編譯器強(qiáng)制執(zhí)行,否則case語句不需要括號(hào)。 當(dāng)某個(gè)case包含多行語句時(shí),應(yīng)添加大括號(hào);多個(gè)條件執(zhí)行相同語句時(shí),去掉break 會(huì)有 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;
}

使用枚舉類型作為開關(guān)時(shí),不需要“ default”

JSTLeftMenuTopItemType menuType = JSTLeftMenuTopItemMain;
switch (menuType) {
  case JSTLeftMenuTopItemMain:
    // ...
    break;
  case JSTLeftMenuTopItemShows:
    // ...
    break;
  case JSTLeftMenuTopItemSchedule:
    // ...
    break;
}

Private Properties 私有屬性

私有屬性應(yīng)該申明在類擴(kuò)展(匿名分類)中的.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應(yīng)該用于CoreFoundation,C,C++
由于nil解析為NO,因此無需在條件下進(jìn)行比較

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 條件語句

有條件的主體應(yīng)該總是使用大括號(hào),即使條件主體可以沒有大括號(hào)(例如,它只是一行)來防止錯(cuò)誤。

Preferred:
if (!error) {
  return success;
}

Not Preferred:
if (!error)
  return success;
or
if (!error) return success;

Ternary Operator 三元運(yùn)算符

三元運(yùn)算符?:只應(yīng)在增加清晰度或代碼整潔度時(shí)使用。 一個(gè)條件通常都應(yīng)該被評(píng)估。 評(píng)估多個(gè)條件通常更容易理解為if語句,或重構(gòu)為實(shí)例變量。 通常,三元運(yùn)算符的最佳用途是在賦值變量和決定使用哪個(gè)值期間。

應(yīng)該將非布爾變量與某些內(nèi)容進(jìn)行比較,并添加括號(hào)以提高可讀性。 如果要比較的變量是布爾類型,則不需要括號(hào)。

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方法應(yīng)遵循Apple生成的代碼模板提供的約定。還應(yīng)使用返回類型“instancetype”而不是“id”。

- (instancetype)init {
  self = [super init];
  if (self) {
    // ...
  }
  return self;
}

Class Constructor Methods 類構(gòu)造方法

在使用類構(gòu)造函數(shù)方法的地方,這些方法應(yīng)始終返回'instancetype'類型而不是'id'。 這可確保編譯器正確推斷結(jié)果類型。

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

@end

CGRect Functions CGRect功能

訪問CGRect的x,y,width或height時(shí),始終使用CGGeometry函數(shù)而不是直接的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 黃金路徑

使用條件編碼時(shí),代碼的左邊距應(yīng)為“黃金”或“快樂”路徑。 也就是說,不要嵌套if語句。 多個(gè)return語句都可以。

Preferred:
- (void)someMethod {
  if (![someOther boolValue]) {
    return;
  }
  //Do something important
}

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

Error handling 錯(cuò)誤處理

當(dāng)方法通過引用返回錯(cuò)誤參數(shù)時(shí),請(qǐng)打開返回的值,而不是錯(cuò)誤變量。
在成功的情況下,Apple的某些API會(huì)將垃圾值寫入錯(cuò)誤參數(shù)(如果為非NULL),因此啟用錯(cuò)誤可能會(huì)導(dǎo)致錯(cuò)誤否定(并隨后崩潰)。

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

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

Singletons 單例

Singleton對(duì)象應(yīng)使用線程安全模式來創(chuàng)建其共享實(shí)例。

+ (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非常突出的風(fēng)格特征! 擁有正確的微笑非常重要,這標(biāo)志著編碼主題的巨大快樂和興奮。 使用末端方括號(hào)是因?yàn)樗砹四軌蚴褂胊scii藝術(shù)捕獲的最大微笑。 如果使用末端括號(hào),則表示半心半意的微笑,因此不是優(yōu)選的。

Preferred:
:]

Not Preferred:
:)

Xcode project

物理文件應(yīng)與Xcode項(xiàng)目文件保持同步,以避免文件蔓延。 創(chuàng)建的任何Xcode組都應(yīng)該由文件系統(tǒng)中的文件夾反映出來。 代碼不僅應(yīng)按類型分組,還應(yīng)按功能分組,以便更清晰。

如果這篇文章對(duì)您有用,煩請(qǐng)點(diǎn)個(gè)贊,這是對(duì)小弟最大的支持,謝謝

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 這是16年5月份編輯的一份比較雜亂適合自己觀看的學(xué)習(xí)記錄文檔,今天18年5月份再次想寫文章,發(fā)現(xiàn)簡書還為我保存起的...
    Jenaral閱讀 3,142評(píng)論 2 9
  • 這里有些關(guān)于編碼風(fēng)格Apple官方文檔,如果有些東西沒有提及,可以在以下文檔來查找更多細(xì)節(jié): The Object...
    Loki9527閱讀 417評(píng)論 0 0
  • 一、命名規(guī)范 1、統(tǒng)一要求含義清楚,盡量做到不需要注釋也能了解其作用,若做不到,就加注釋,使用全稱,不使用縮寫。 ...
    Untils閱讀 620評(píng)論 0 0
  • 概要 Objective-C是一門面向?qū)ο蟮膭?dòng)態(tài)編程語言,主要用于編寫iOS和Mac應(yīng)用程序。關(guān)于Objectiv...
    DreamMmMmM閱讀 1,271評(píng)論 0 7
  • 朗境科技 移動(dòng)團(tuán)隊(duì) 郎鏡通代碼規(guī)范指南 介紹 關(guān)于這個(gè)編程語言的所有規(guī)范,如果這里沒有寫到,那就在蘋果的文檔里:...
    百事小武閱讀 946評(píng)論 1 2

友情鏈接更多精彩內(nèi)容