Coder Social home page Coder Social logo

vivalalova / objective-c-style-guide Goto Github PK

View Code? Open in Web Editor NEW

This project forked from yehnan/objective-c-style-guide

0.0 2.0 1.0 72 KB

紐約時報行動軟體團隊的Objective-C程式碼撰寫風格手冊

Home Page: http://open.blogs.nytimes.com/2013/08/01/objectively-stylish/

License: MIT License

objective-c-style-guide's Introduction

紐約時報行動軟體團隊的Objective-C程式碼撰寫風格手冊

這份手冊摘要描述紐約時報iOS開發團隊的程式碼書寫慣例。歡迎各位回饋意見,提出問題提出pull請求、以及發推文,另外,我們正招募中

感謝所有的貢獻者

導論

底下列出一些Apple公司關於程式碼風格與慣例的文件,若你發現某事項本手冊並未提及,通常都能在這些文件裡找到詳細的描述。

目錄

句點標記法的語法(Dot-Notation Syntax)

使用句點標記法的地方一定是想要存取與改變屬性的時候,任何其他地方應採用方括號標記法。

譬如應該如下這樣寫:

view.backgroundColor = [UIColor orangeColor];
[UIApplication sharedApplication].delegate;

而不是這樣寫:

[view setBackgroundColor:[UIColor orangeColor]];
UIApplication.sharedApplication.delegate;

空格與縮排(Spacing)

  • 縮排時使用4個空白,千萬不要使用tab鍵,記得在Xcode的偏好設定裡啟用此選項。
  • 方法的大括號與其他程式構件的大括號(if/else/switch/while等等),左大括號必須跟程式構件位於同一行,但右大括號則位於新的一行。

例如:

if (user.isHappy) {
//作事情
}
else {
//作事情
}
  • 方法之間必須恰好相隔一個空白行,有助於程式碼整體組織性與視覺辨識。方法內也可用空白行區隔功能,但碰到這種情況時,通常就是該分出新方法的時候。
  • 在實作裡的@synthesize@dynamic,每個必須單獨宣告佔據一行。

條件判斷(Conditionals)

條件判斷的主體一定要包在大括號裡,就算是能省略大括號(也就是說,主體只有一行),可避免各種 錯誤,常見錯誤包括,之後加入第二行程式碼卻以為它會被if述句所涵蓋, 另一個會出錯且更加危險的錯誤是,當if述句「裡」唯一一行程式碼被註解掉後,下一行卻變成if述句的主體了。另外,這項書寫慣例能與其他條件判斷式保持一致性,檢查程式碼時更容易被找出錯誤。

譬如:

if (!error) {
    return success;
}

而不是:

if (!error)
    return success;

if (!error) return success;

方法(Methods)

方法宣告時,在-/+符號之後必須是一個空白。方法每個參數區段之間必須相隔一個空白。

例如::

- (void)setExampleText:(NSString *)text image:(UIImage *)image;

變數(Variables)

盡量以淺顯易懂的方式命名變數,避免使用只有一個字元的變數名,除了在for()裡。

星號指出指標屬於變數,例如NSString *text,而不是NSString* textNSString * text,除非碰到常數的情況。

只要可以,都應該以屬性定義取代單純的實體變數。應避免直接存取實體變數,除了在初始化方法(initinitWithCoder:、等等)、dealloc方法、以及自訂的取值子與設值子方法。關於在初始化方法與dealloc方法裡使用存取子方法,更多細節請見這裡

例如:

@interface NYTSection: NSObject

@property (nonatomic) NSString *headline;

@end

而不是:

@interface NYTSection : NSObject {
    NSString *headline;
}

命名(Naming)

不論如何,都應該盡量遵守Apple的命名規則,特別是關於記憶體管理 (NARC)部份的規則。

夠長且一看就懂的方法名與變數名,是好事。

例如:

UIButton *settingsButton;

而不是:

UIButton *setBut;

類別名與常數應冠上由三字母組成的字頭(譬如NYT),但Core Data的entity名可省略。常數應採用駝峰式大小寫命名法,每個單字的第一個字母應大寫,為了清楚起見冠上相關的類別名。

例如:

static const NSTimeInterval NYTArticleViewControllerNavigationFadeAnimationDuration = 0.3;

而不是:

static const NSTimeInterval fadetime = 1.7;

屬性名也採用駝峰式大小寫命名法,但開頭單字應小寫,注意:若Xcode能自動合成實體變數,就讓它負責;否則,屬性背後的實體變數的名字,應採用駝峰式大小寫命名法但開頭單字小寫,並加上底線(_),這也是Xcode合成名字時的預設規則。

例如:

@synthesize descriptiveVariableName = _descriptiveVariableName;

而不是:

id varnm;

底線(Underscores)

使用屬性時,一定使用self.來存取實體變數,這麼一來,一看就能看出所有的屬性,因為其前頭都有self.。區域變數不該含有底線。

註解(Comments)

當需要寫註解時,其功用應該是試著解釋「為什麼」這一段程式碼做了某件事。任何註解都應該隨時更新,否則就該刪除。

一般來說,應避免使用區塊型註解,因為程式碼應盡量保持「一看就能明白」的樣子,只需要偶爾插入少數幾行的說明描述即可。但這項慣例不適用於用來產生文件的註解。

初始化與解構式(init and dealloc)

dealloc方法應位於實作的最上方,緊跟著 @synthesize@dynamic,而init方法應置於dealloc 之下。

字面值(Literals)

建立NSStringNSDictionaryNSArray、與NSNumber的不可變物件時,應使用其字面值。請特別注意, 不可將nil值放進NSArrayNSDictionary的字面值,將會導致當掉。

例如:

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 Functions)

存取CGRectxywidth、或height時,一律使用CGGeometry函式,而不要直接存取結構成員。摘錄Apple的CGGeometry參考文件:

本參考文件中,所有接受CGRect資料結構作為輸入的函式,都會暗中將這些矩形予以標準化,所以,您的程式碼應避免直接讀寫存放在CGRect裡的資料,反之,請使用此處列出的函式來操作矩形與各項特性。

例如:

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;

常數(Constants)

比起在程式碼裡直接寫入字串字面值或數字,較佳的作法是使用常數,這麼一來便能輕易地重複使用,想修改時也很方便,不需要大海撈針逐一更動。常數應宣告為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

列舉型別(Enumerated Types)

使用enum時,建議使用擁有底層固定型別的新型宣告,因為可得到更佳的型別檢查與程式碼補齊功能;SDK裡含有巨集NS_ENUM(),方便我們加以運用。

例如:

typedef NS_ENUM(NSInteger, NYTAdRequestState) {
    NYTAdRequestStateInactive,
    NYTAdRequestStateLoading
};

私有屬性(Private Properties)

私有屬性應宣告在類別實作檔裡的類別延伸(class extension)裡,也就是無名類目(anonymous category),不該使用有名的類目(例如NYTPrivateprivate),除非你想要延伸擴充某類別。

例如:

@interface NYTAdvertisement ()

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

@end

圖檔命名(Image Naming)

請務必讓圖檔名保持一致性,便於管理,才不會讓開發人員發瘋,應採用駝峰式大小寫命名法,首先詳細地描述出該圖檔的用途,然後跟著與它們相關、不帶有前置字串的類別名或屬性名(若有的話),然後跟著顏色、編排等資訊,最後是圖檔的狀態。

例如:

  • RefreshBarButtonItem / RefreshBarButtonItem@2xRefreshBarButtonItemSelected / RefreshBarButtonItemSelected@2x
  • ArticleNavigationBarWhite / ArticleNavigationBarWhite@2xArticleNavigationBarBlackSelected / ArticleNavigationBarBlackSelected@2x.

用途類似的圖檔,應置於Images目錄下,分門別類放在相對應的群組之下。

布林(Booleans)

因為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) // 千萬別這麼寫

若BOOL屬性的名字是個形容詞,那麼可省略“is”前置字串,但可為取值子方法設定約定俗成的名稱,例如:

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

描述與範例取自Cocoa Naming Guidelines

單件設計模式(Singletons)

建立共享的單件物件時,應使用執行緒安全的寫法。 Singleton objects should use a thread-safe pattern for creating their shared instance.

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

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

   return sharedInstance;
}

這麼做可免除[各種可能出現的臭蟲與錯誤] (http://cocoasamurai.blogspot.com/2011/04/singletons-your-doing-them-wrong.html)。

Xcode專案(Xcode project)

實體檔案應隨時與Xcode專案檔保持同步,避免檔案四處流散;Xcode專案裡的群組(group)必須在檔案系統中有其相對應的目錄;不僅要根據類型區分程式碼,也要根據功能加以劃分,使之更為清晰。

盡量啟用建構標的之Treat Warnings as Errors這項建構設定,並盡量啟用額外的警告,越多越好,若你需要忽略某一項特定的警告,可使用Clang的pragma功能

其他關於Objective-C程式碼撰寫風格的手冊

如果我們的規範並不符合您的口味,請看看其他人的風格手冊:

objective-c-style-guide's People

Contributors

mbbischoff avatar yehnan avatar bcapps avatar jacobvanorder avatar dlo avatar eerwitt avatar jawwad avatar jfiore avatar maxgabriel avatar twigz avatar yas375 avatar

Watchers

James Cloos avatar Lova avatar

Forkers

fletcherchen

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.