NYTimes Objective-C 編程風格指南。來源:
https://github.com/NYTimes/objective-c-style-guide
這篇指南總結了紐約時報iOS開發團隊的編程風格。歡迎你們在github中提供建議和pull請求。
簡介:
如下是造成本編程指南所涉及到的Apple官方文檔。若是本文有未盡之處,能夠參考如下連接:
目錄
點表示法
空格
條件語句
三元運算子
方法
變量
命名
下劃線
註釋
初始化&內存釋放
Literals字面量
CGRect 函數
常量
枚舉類型
私有屬性
圖片名稱
布爾變量
單例
Xcode項目
點表示法應「僅」用於獲取和改變屬性。括號表示法用於全部其它實例。
例如:
恰當用法:
view.backgroundColor = [UIColor orangeColor]; [UIApplication sharedApplication].delegate;
不當用法:
[view setBackgroundColor:[UIColor orangeColor]]; UIApplication.sharedApplication.delegate;
空格
(1)行縮進使用4個空格。禁止使用Tab鍵來縮進。請在Xcode偏好設置中進行設置。
(2)方法大括號和其它大括號(好比if/else/switch/while等等)應在語句的同一行開始,而在新的一行關閉。
例如:
if (user.isHappy) { //Do something } else { //Do something else }
(3)爲保證視覺上的整潔和代碼組織,在方法之間應提供且僅提供一行空白。方法中的空白應用於區分功能,但空白行最好用於區分兩個不一樣方法。
(4)@synthesize和@dynamic應在方法實現的新一行中聲明。
條件語句
爲避免錯誤,條件語句體必須使用大括號,即使語句體中的語句能夠沒必要使用大括號(好比只有一行語句)。常見的錯誤包括在不使用大括號的狀況下添加第二行語句,覺得它屬於if語句的一部分。此外,更可怕的事情是,若是條件語句中的代碼行被註釋,則本不術語條件語句的下一行代碼將變成條件語句的一部分。此外,這種編碼風格和全部其它條件語句均保持一致。
例如:
恰當用法:
if (!error) { return success; }
不當用法:
if (!error) return success;
不當用法2:
if (!error) return success;
三元運算子
僅當使用該運算子可讓代碼顯得更清晰易懂時方可以使用三元運算子。更多狀況下應使用條件語句。使用相似if的條件語句對多種條件進行判斷一般要更容易理解,或使用實例變量。
恰當用法:
result = a > b ? x : y;
不當用法:
result = a > b ? x = c > d ? c : d : y;
方法
在方法聲明中,在(-/ )符號以後應加上一個空格。此外,在方法段之間應添加一個空格。
例如:
(void)setExampleText:(NSString *)text image:(UIImage *)image;
變量
變量的命名應儘量具備自解釋性。除了在for()循環語句中,應避免使用單個字母變量名稱。
除非是常量,星號應緊貼變量名稱表示指向變量的指針,好比:
正確用法:
NSString *text;
不當用法:
NSString* text; NSString * text;
應儘量使用屬性定義替代單一的實例變量。避免在初始化方法,dealloc方法和自定義的setter和getter方法中直接讀取實例變量參數(init,initWithCoder:,等等)。更多信息請參看here
例如:
恰當用法:
@interface NYTSection: NSObject @property (nonatomic) NSString *headline; @end
不當用法:
@interface NYTSection : NSObject { NSString *headline; }
命名規範
蘋果的命名規範應儘量符合內存管理法則(NARC)memory management rules
在Objective-C中鼓勵使用長的描述性的方法和變量名稱。
例如:
恰當用法:UIButton *settingsButton;
不當用法:
UIButton *setBut;
對於類和常量名稱,應儘可能使用三大寫字母前綴(好比NYT),但對Core Data的實體名稱可不適用該法則。
常量名稱應將其中的全部單詞的首字母大寫,同時加上相關類的名稱做爲前綴。
例如:
恰當用法:
static const NSTimeInterval NYTArticleViewControllerNavigationFadeAnimationDuration = 0.3;
不當用法:
static const NSTimeInterval fadetime = 1.7;
屬性名稱應使用camel-case(駝峯式)命名方法,且第一個單詞的首字母應爲小寫。若是Xcode版本支持對變量的自動合成,則沒必要深究。不然與該屬性對應的實例變量名稱的第一個單詞的首字母應爲小寫,且在前面加上下劃線。
例如:
恰當用法:
@synthesize descriptiveVariableName = _descriptiveVariableName;
不當用法:
id varnm;
下劃線
當使用屬性變量時,應經過self.來獲取和更改實例變量。這就意味着全部的屬性將是獨特的,由於它們的名稱前會加上self.。本地變量名稱中不該包含下劃線。
註釋
在須要註釋的地方,應使用註釋來解釋某一塊特定的代碼的功能。全部的代碼註釋必須是最新的,要嗎就刪掉。
應儘可能使用行註釋,而避免使用塊註釋。之因此這樣是由於代碼自身須要是自文檔化的,所以只須要零散添加一些行註釋。固然,對於用於生成文檔的註釋,該原則並不適用。
初始化和內存釋放
dealloc方法應放在方法實現文件的頂部,在@synthesize和@dynamic語句以後。init初始化方法應放在dealloc方法以後。
Literals字面量
在建立NSString,NSDictionary,NSArray和NSNumber等對象的immutable實例時,應使用字面量。須要注意的是,不該將nil傳遞給NSArray和NSDictionary字面量,不然會引發程序崩潰。
例如:
恰當用法:
NSArray *names = @[@"Brian", @"Matt", @"Chris", @"Alex", @"Steve", @"Paul"]; NSDictionary *productManagers = @{@"iPhone" : @"Kate", @"iPad" : @"Kamal", @"Mobile Web" : @"Bill"}; NSNumber *shouldUseLiterals = @YES; NSNumber *buildingZIPCode = @10018;
不當用法:
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 *ZIPCode = [NSNumber numberWithInteger:10018];
CGRect函數
當須要獲取一個CGRect矩形的x,y,width,height屬性時,應使用CGGeometry函數,而非直接訪問結構體成員。
例如:
恰當用法:
CGRect frame = self.view.frame; CGFloat x = CGRectGetMinX(frame); CGFloat y = CGRectGetMinY(frame); CGFloat width = CGRectGetWidth(frame); CGFloat height = CGRectGetHeight(frame);
不當用法:
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;
常量
相對字符串字面量或數字,咱們更推薦適用常量。應使用static方式聲明常量,而非使用#define的方式來定義宏。
例如:
恰當用法:
static NSString * const NYTAboutViewControllerCompanyName = @"The New York Times Company"; static const CGFloat NYTImageThumbnailHeight = 50.0;
不當用法:
#define CompanyName @"The New York Times Company" #define thumbnailHeight 2
枚舉類型
在使用enum的時候,推薦適用最新的fixed underlying type(WWDC 2012 session 405- Modern Objective-C)規範,由於它具有更強的類型檢查和代碼完成功能。
例如:
typedef NS_ENUM(NSInteger, NYTAdRequestState) {
NYTAdRequestStateInactive,
NYTAdRequestStateLoading
};
私有屬性
私有屬性應在類實現文件的類擴展(匿名分類)中進行聲明。應避免使用命名分類(好比NYTPrivate或private)。
例如:
@interface NYTAdvertisement () @property (nonatomic, strong) GADBannerView *googleAdView; @property (nonatomic, strong) ADBannerView *iAdView; @property (nonatomic, strong) UIWebView *adXWebView; @end
圖片名稱
在命名圖片名稱的時候,應保持一致性,從而讓開發團隊和成員能夠明白其含義。圖片名稱的第一個單詞應描述其用途,並使用camel-case風格,而後是不帶前綴的所屬類名稱或屬性,最後是色彩、位置和狀態。
例如:
RefreshBarButtonItem / RefreshBarButtonItem@2x and RefreshBarButtonItemSelected / RefreshBarButtonItemSelected@2x ArticleNavigationBarWhite / ArticleNavigationBarWhite@2x and ArticleNavigationBarBlackSelected / ArticleNavigationBarBlackSelected@2x.
布爾變量
由於nil將被解析爲NO,所以沒有必要在條件語句中進行比較。永遠不要將任何東西和YES進行直接比較,由於YES被定義爲1,而一個BOOL變量能夠有8個字節。
例如:
恰當用法:
if (!someObject) {}
不當用法:
if (someObject == nil) { }
如下是BOOL變量的使用:
恰當用法:
if (isAwesome) if (![someObject boolValue])
不當用法:
if ([someObject boolValue] == NO) if (isAwesome == YES) // Never do this.
若是一個BOOL屬性使用形容詞來表達,屬性將忽略’is’前綴,但會強調慣用名稱。
例如:
@property (assign, getter=isEditable) BOOL editable;
單例
在建立單例對象的共享實例時,應使用線程安全模式。
例如:
(instancetype)sharedInstance { static id sharedInstance = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ sharedInstance = [[self alloc] init]; }); return sharedInstance; }
Xcode項目
爲避免文件混亂,實際的物理文件應和Xcode項目保持一直。在Xcode中所建立的任何group都應有文件系統中相對應的文件夾。不該僅根據文件類型來進行分組,還須要考慮到其做用。
在Xcode的target的Build Setting中,中儘可能開
啓」Treat Warnings as Errors「,同時儘可能開啓其餘的警告
additional warnings。若是須要忽略某個特定的警告,可使用
Clang's pragma feature
若是以上編碼風格不合你的口味,還能夠參考如下幾個風格指南: