1.建議開(kāi)git的feature分支開(kāi)發(fā)
2.合入Duckbill分支的兩人review
3.每一個(gè)提交都是讓代碼變整潔,遵守styleguide
4.對(duì)復(fù)雜的controller建議采用MVVM
5.鼓勵(lì)寫(xiě)單元測(cè)試
6.鼓勵(lì)結(jié)對(duì)編程
介紹
這份規(guī)范指南概括了XXXX使用 Objective-C 時(shí)所遵循的代碼約定。關(guān)于這個(gè)編程語(yǔ)言的所有規(guī)范,如果這里沒(méi)有寫(xiě)到,請(qǐng)參考蘋(píng)果文檔:
示例代碼如下:
typedef NS_ENUM(NSInteger, StyleGuideFormat) {
StyleGuideFormatLeft,
StyleGuideFormatRight,
StyleGuideFormatUp,
StyleGuideFormatDown
};
static NSString * const StyleGuideDidChangedNotification = @"StyleGuideDidChangedNotification";
static NSString * const StyleGuideUserInfoKey = @"StyleGuideUserInfoKey";
static NSString * const StyleGuideInvalidFormatException = @"StyleGuideInvalidFormatException";
static const NSInteger StyleGuideTotalCount = 100;
@interface StyleGuide () <NSCopying, NSMutableCopying, NSSecureCoding, NSFastEnumeration> {
NSArray *_defaultStyleGuides;
NSString *_currentName;
}
@property (nonatomic, readonly, getter = isEditable) BOOL editable;
@property (nonatomic, readwrite) NSDictionary *userInfo;
@end
@interface StyleGuide (StyleGuideExtendedMethod)
- (BOOL)TT_isReady;
- (void)sortWithName:(NSString *)name;
- (NSString *)title;
- (NSString *)titleAsASCIIEncoding;
@end
@implementation StyleGuide
- (void)dealloc {
[super dealloc];
}
- (instancetype)init {
self = [super init];
if (self != nil) {
//Custom initialization
}
return self;
}
- (NSInteger)count {
NSInteger keyCount = 10;
NSInteger objectCount = 20;
NSInteger total = keyCount + objectCount;
return total;
}
@end
@implementation StyleGuide (ExtendedMethod)
- (BOOL)TT_isReady {
BOOL isFinished = ([self hasFinished] ? YES : NO);
if (isFinished) {
} else {
}
}
@end
格式
縮進(jìn)
一個(gè)縮進(jìn)使用 4 個(gè)空格,永遠(yuǎn)不要使用制表符(tab)縮進(jìn)。
空行
不同的模塊之間以空行相隔,這有助于視覺(jué)清晰度和代碼組織性,有以下幾種(示例代碼參考本指南開(kāi)頭的代碼):
- @interface, @implementation, @protocol, @end, @optional, @required 與相鄰的模塊之間應(yīng)該有空一行。
- 方法體實(shí)現(xiàn)之間應(yīng)該正好空一行。
變量
- 指針類型變量 * 應(yīng)緊靠變量名。
- 在ARC中擁有性限定符(__strong, __weak, __unsafe_unretained, __autoreleasing)以及 __block 應(yīng)位于類型名之前。
推薦:
NSString *name;
__weak NSString *name;
__block NSString *name;
反對(duì):
NSString* name;
NSString*name;
NSString * name;
常量
- 定義指針類型的常量時(shí),const 位于 * 之后,且以空格相隔。
- 定義值類型的常量是, const 位于類型名之前。
推薦:
NSString * const Name = @"John";
const int TotalNum = 100;
運(yùn)算符
單目運(yùn)算符如 !, & 等與運(yùn)算對(duì)象之間無(wú)空格。
多目運(yùn)算符與運(yùn)算對(duì)象之間以空格相隔。
-
三目運(yùn)算符 ? 應(yīng)以 () 括起來(lái)。
推薦:
int result = (isTrue ? number1 : number2); -
如果一行出現(xiàn)過(guò)多的
&&/||而需要分行時(shí),&&/||置于每行行尾。推薦:
if (self.count == another.count && self.name == another.name && self.title == another.name &&) { }
程序塊
方法的大括號(hào)和其他的大括號(hào)(if/else/switch/while 等等)始終和聲明在同一行開(kāi)始,在新的一行結(jié)束。
推薦:
if (user.isHappy) {
// Do something
} else {
// Do something else
}
方法頭
- 在方法簽名中,在 -/+ 符號(hào)后應(yīng)該有一個(gè)空格。
- 返回值類型與方法名之間沒(méi)有空格。
推薦:
- (void)setExampleText:(NSString *)text image:(UIImage *)image;
多參數(shù)方法
當(dāng)一個(gè)方法包含多個(gè)參數(shù)時(shí),可以考慮每行一個(gè)參數(shù),以 : 對(duì)齊。
推薦:
[NSError errorWithName:
withType:
withCode:];
當(dāng)方法名中存在名字片段過(guò)長(zhǎng)或者過(guò)短而無(wú)法以 : 對(duì)齊時(shí),建議從第二行開(kāi)始每行縮進(jìn)四個(gè)空格。
推薦:
[error short:
keyName:
lastLongKeyName:];
函數(shù)頭
- 非指針?lè)祷仡愋团c函數(shù)名之間有一個(gè)空格。
- 類型與 * 之間有一個(gè)空格。
- 指針?lè)祷仡愋团c函數(shù)名之間無(wú)空格。
推薦:
NSData *UIImagePNGRepresentation(UIImage *image);
void CFRelease(CFTypeRef cf);
(), <>, {}, @[], @{}
-
(), <>, {} 與相鄰的模塊之間應(yīng)該以空格分隔。
推薦:
if () { } else { } @interface NSObject <NSObject>以下幾種情況除外。
-
函數(shù)聲明、定義和調(diào)用。
推薦:
NSData *UIImagePNGRepresentation(UIImage *image); UIImagePNGRepresentation(originalImage); -
方法聲明和定義。
推薦:
- (instancetype)initWithImage:(UIImage *)image; -
強(qiáng)制類型轉(zhuǎn)換。
推薦:
int count = (int)5.0f; tip = (__bridge_transfer NSString *)CFSTR("Hello World"); -
enum 和 bitmask 定義。
推薦:
typedef NS_ENUM(NSUInteger, NSExpressionType) typedef NS_OPTIONS(NSUInteger, SDWebImageDownloaderOptions)
-
-
(), <>, @[], @{} 與其包含的元素之間無(wú)空格。
推薦:
(void) id<Protocol1> ((x = y)) @[@1] array[0] @{@“key”: @"value"} dictionary[@"key"]反對(duì):
( void ) id< Protocol1 > ( ( x = y ) ) @[ @1 ] array[ 0 ] @{ @“key”: @"value" } dictionary[ @"key" ] -
(), <>, @[], @{} 其內(nèi)包含的元素之間以,空格相隔。
推薦:
(1, 2, 3) id<Protocol1, Protocol2> @[@1, @2, @3] @{@"k": @"v", @"m": @"n"}反對(duì):
(1,2,3) id<Protocol1,Protocol2> @[@1,@2,@3] @{@"k": @"v",@"m": @"n"} -
@{} 中鍵值應(yīng)以:空格分隔。
推薦:
@{@"k": @"v"}反對(duì):
@{@"k":@"v"}如果@{}中包含多個(gè)鍵值對(duì),則建議每行一個(gè)鍵值對(duì)且左對(duì)齊。
推薦:
@{ @"k": @"v", @"m": @"n" }反對(duì):
@{@"k": @"v", @"m": @"n"} -
<> 中包含多個(gè)協(xié)議,可考慮分行。從次行開(kāi)始每個(gè)協(xié)議名左對(duì)齊于第一個(gè)協(xié)議名。
推薦:
@protocol UITableViewDelegate <NSObject, UIScrollViewDelegate>
類
: 兩邊以空格相連。如下:
推薦:
@interface NSString : NSObject <NSCopying, NSMutableCopying, NSSecureCoding>
@interface NSString () <NSCopying, NSMutableCopying, NSSecureCoding>
屬性
按照原子性、可讀性、擁有性、以及自定義 Accesor Method 方法順序排列,默認(rèn)值可省去。
推薦:
@property (nonatomic, readonly, copy, setter = setTitle) NSString *title;
命名
本部分大部分內(nèi)容來(lái)自于Cocoa 編碼指南,如果這里沒(méi)有提及,請(qǐng)參考Cocoa 編碼指南。
采用 camel-casing 命名法:將每個(gè)單詞的首字母大寫(xiě)然后拼接起來(lái)。
基本原則
-
清晰
- 命名的清晰性高于簡(jiǎn)單和簡(jiǎn)潔,應(yīng)在追求清晰的同時(shí)盡量保持簡(jiǎn)潔。
- 盡量避免使用縮寫(xiě),即使很長(zhǎng)也要拼寫(xiě)出來(lái)。
- 一些通用的縮寫(xiě)普遍使用,可以參考通用的縮寫(xiě)。
- 避免二義性。
-
一致性
盡量保持命名在整個(gè)程序內(nèi)的一致性,主要包含兩點(diǎn):
- 同一名字表示相同的意義。
- 同樣的概念使用同一名字表示,切忌同時(shí)使用多個(gè)名字。
前綴
- 應(yīng)用程序代碼不建議使用前綴,當(dāng)開(kāi)發(fā)第三方使用的庫(kù)時(shí)則應(yīng)該使用前綴。
- 協(xié)議名、函數(shù)名、常量名、以及枚舉名應(yīng)以其所關(guān)聯(lián)的類名作為前綴。
推薦:
typedef NS_ENUM(NSInteger, UIScreenOverscanCompensation);
NSString *const UIScreenDidConnectNotification;
NSData *UIImagePNGRepresentation(UIImage *image);
@protocol UIAlertViewDelegate <NSObject>
類
類名通常應(yīng)該由名詞組成,并完全遵循 camel-casing。
協(xié)議
協(xié)議名字通常根據(jù)其包含的方法而定,有以下幾類:
-
包含了一些相關(guān)的方法,通常作為一組類的接口,其命名方式為:操作 + ing。
推薦:
@protocol NSLocking - (void)lock; - (void)unlock; @end @protocol NSCopying - (id)copyWithZone:(NSZone *)zone; @end -
包含一組相關(guān)的方法,用于在代理對(duì)象和被代理對(duì)象之間傳遞數(shù)據(jù),其命名方式為:類名 + DataSource。
推薦:
@protocol UITableViewDataSource<NSObject> -
包含一組相關(guān)的方法, 用于響應(yīng)操作和控制程序流,其命名方式為:類名 + Delegate。
推薦:
@protocol UIAlertViewDelegate <NSObject> @optional - (void)alertView: clickedButtonAtIndex: ; - (BOOL)alertViewShouldEnableFirstOtherButton:; 包含一組不相關(guān)的方法,關(guān)聯(lián)到一個(gè)類上,其命名方式為:類名。參考 NSObject。
變量
變量名字采用 camel-casing 命名法且首字母小寫(xiě)。
-
對(duì)于數(shù)組類型的變量,其命名方式為:名詞/詞組 + s。
推薦:
NSMutableArray *gestureRecognizers;反對(duì):
NSMutableArray *gestureRecognizerArray; -
對(duì)于字典類型的變量,其命名方式為:名詞/詞組 + s/Info。
推薦:
NSDictionary *fileAttributes; NSDictionary *userInfo;反對(duì):
NSDictionary *fileAttributeDictionary; NSDictionary *userDictionary; 實(shí)例變量遵從變量的命名方式,且以 _ 為前綴。
屬性
屬性遵從變量的命名方式,如果屬性名字是形容詞,需指定 get 訪問(wèn)器。
推薦:
@property (nonatomic, readonly, getter = isPlayable) BOOL playable;
枚舉
枚舉常量的名字應(yīng)以枚舉變量的名字為前綴,其命名方式為:枚舉類型 + 枚舉狀態(tài)。枚舉類型的命名方式為:類名 + 名詞/詞組。
推薦:
typedef NS_ENUM(NSInteger, NSOperationQueuePriority) {
NSOperationQueuePriorityVeryLow = -8L,
NSOperationQueuePriorityLow = -4L,
NSOperationQueuePriorityNormal = 0,
NSOperationQueuePriorityHigh = 4,
NSOperationQueuePriorityVeryHigh = 8
};
通知
通知命名方式:[Name of associated class] + [Did | Will] + [UniquePartOfName] + Notification
推薦:
NSSystemTimeZoneDidChangeNotification
MPMediaLibraryDidChangeNotification
UIKeyboardWillShowNotification
異常
異常命名方式:[Name of associated class] + [UniquePartOfName] + Exception。
推薦:
NSRangeException
NSInvalidArgumentException
鍵
鍵指鍵值對(duì)中的鍵,用在字典中。其命名方式:[Name of associated class] + [UniquePartOfName] + Key。
推薦:
UIKeyboardFrameBeginUserInfoKey
ALAssetLibraryUpdatedAssetsKey
方法
方法命名遵從變量的命名方式。
-
對(duì)于表示動(dòng)作的方法,以動(dòng)詞開(kāi)頭。
不要使用 do 或者 does 等很少有意義的語(yǔ)氣助詞。另外,不要在動(dòng)詞前使用副詞或形容詞。
-
對(duì)于返回對(duì)象屬性的方法,建議直接使用屬性作為方法名。
反對(duì)使用 get 作為前綴,或者其他的動(dòng)詞,即使該方法并非直接返回結(jié)果,而是需要一些運(yùn)算。存在多個(gè)返回值時(shí),則
推薦:
- (NSSize)cellSize;反對(duì):
- (NSSize)calcCellSize; - (NSSize)getCellSize; -
在所有參數(shù)前都要有關(guān)鍵字。
推薦:
- (void)sendAction:(SEL)aSelector toObject:(id)anObject;反對(duì):
- (void)sendAction:(SEL)aSelector :(id)anObject; -
描述參數(shù)的詞緊靠在參數(shù)之前。
推薦:
- (id)viewWithTag:(NSInteger)aTag;反對(duì):
- (id)taggedView:(int)aTag; -
針對(duì) Cocoa 或 第三方庫(kù)中的類所添加的類別中的方法,需為方法名添加前綴,基于項(xiàng)目名的縮寫(xiě)構(gòu)成前綴,形如
TT_。對(duì)于派生自他們的子類,如果擔(dān)心添加的方法可能會(huì)跟基類中得方法名沖突,通用建議使用前綴方法名。考慮這樣一個(gè)場(chǎng)景,在8.0發(fā)布之前你為 NSString 添加了一個(gè)類別,其中包含一個(gè)這樣的方法 *containsString:(NSString )aString 。待到8.0發(fā)布時(shí),蘋(píng)果不幸地意識(shí)到確實(shí)需要一個(gè)這樣的方法,在 NSString 中新增了同樣的一個(gè)接口,這絕對(duì)是災(zāi)難性地!
函數(shù)
函數(shù)命名法類似方法,除了兩點(diǎn):
- 第一個(gè)詞的首字母需大寫(xiě)。
- 遵從類似于常量和類別等相同的前綴添加規(guī)則。
<span id="jump_1">通用的縮寫(xiě)</span>
| Abbreviation | Meaning and comments |
|---|---|
| alloc | Allocate. |
| alt | Alternate. |
| app | Application. |
| calc | Calculate. |
| dealloc | Deallocate. |
| func | Function. |
| horiz | Horizontal. |
| info | Information. |
| init | Initialize. |
| int | Integer. |
| max | Maximum. |
| min | Minimum. |
| msg | Message. |
| nib | Interface Builder archive. |
| pboard | Pasteboard (but only in constants). |
| rect | Rectangle. |
| Rep | Representation. |
| temp | Temporary. |
| vert | Vertical. |
以下是一些在計(jì)算機(jī)領(lǐng)域比較知名的縮寫(xiě):
ASCII
XML
HTML
URL
RTF
HTTP
TIFF
JPG
PNG
GIF
LZW
ROM
RGB
CMYK
MIDI
FTP
其他
注釋
當(dāng)需要的時(shí)候,注釋?xiě)?yīng)該被用來(lái)解釋 為什么 特定代碼做了某些事情。所使用的任何注釋必須保持最新否則就刪除掉。
通常應(yīng)該避免一大塊注釋,代碼就應(yīng)該盡量作為自身的文檔。
Warning的要求
除了第三方庫(kù),不能引入新的警告
類前置聲明
通常引用一個(gè)類有兩種辦法:一種是通過(guò)#import方式引入;另一種是通過(guò)@class引入;在頭文件中通過(guò)@class引入這個(gè)類作為一個(gè)類型使用,減少頭文件的重復(fù)包,提升編譯效率。在實(shí)現(xiàn)文件中,如果需要引用到被引用類的實(shí)體變量或者方法時(shí),還需要使用#import方式引入被引用類。
頭文件聲明:
@class StyleGuide;
StyleGuide *styleGuide;
實(shí)現(xiàn)文件引入頭文件:
#import @"StyleGuilde.h"
#pragma mark分組
一些類(尤其是一些控制器類)可能很長(zhǎng),方法和函數(shù)彈出菜單可以便于代碼導(dǎo)航。此時(shí)加入#pragma 指令對(duì)代碼進(jìn)行邏輯組織很有效果。提高可讀性
例如:
#pragma mark - Initialization
私有方法屬性定義
外部不需使用的屬性方法成員變量不能暴露到.h文件。在類的.m文件中,采用類別來(lái)實(shí)現(xiàn)私有方法
例如:.m文件中定義
@interface MyClass()
- (void)privateMethod;
@end
小貼士
.語(yǔ)法
應(yīng)該 始終 使用.語(yǔ)法來(lái)訪問(wèn)或者修改屬性,除此之外,不得使用.語(yǔ)法。
推薦:
view.backgroundColor = [UIColor orangeColor];
[UIApplication sharedApplication].delegate;
反對(duì):
[view setBackgroundColor:[UIColor orangeColor]];
UIApplication.sharedApplication.delegate;
條件判斷
條件判斷主體部分應(yīng)該始終使用大括號(hào)括住來(lái)防止出錯(cuò),即使它可以不用大括號(hào)(例如它只需要一行)。這些錯(cuò)誤包括添加第二行(代碼)并希望它是 if 語(yǔ)句的一部分時(shí)。還有另外一種更危險(xiǎn)的,當(dāng) if 語(yǔ)句里面的一行被注釋掉,下一行就會(huì)在不經(jīng)意間成為了這個(gè) if 語(yǔ)句的一部分。此外,這種風(fēng)格也更符合所有其他的條件判斷,因此也更容易檢查。
推薦:
if (isFinished) {
return success;
}
反對(duì):
if (isFinished)
return success;
if (isFinished) return success;
三目運(yùn)算符
三目運(yùn)算符,? ,只有當(dāng)它可以增加代碼清晰度或整潔時(shí)才使用。單一的條件都應(yīng)該優(yōu)先考慮使用,多條件時(shí)通常使用 if 語(yǔ)句會(huì)更易懂。
推薦:
result = (a > b ? x : y);
反對(duì):
result = (a > b ? x = c > d ? c : d : y);
錯(cuò)誤處理
當(dāng)引用一個(gè)返回錯(cuò)誤參數(shù)(error parameter)的方法時(shí),應(yīng)該針對(duì)返回值,而非錯(cuò)誤變量。一些蘋(píng)果的 API 在成功的情況下會(huì)寫(xiě)一些垃圾值給錯(cuò)誤參數(shù)(如果非空),所以針對(duì)錯(cuò)誤變量可能會(huì)造成虛假結(jié)果。
推薦:
NSError *error;
if (![self trySomethingWithError:&error]) {
// 處理錯(cuò)誤
}
反對(duì):
NSError *error;
[self trySomethingWithError:&error];
if (error != nil) {
// 處理錯(cuò)誤
}
init 和 dealloc
dealloc 方法應(yīng)該放在@implementation的最上面,并且剛好在 @synthesize 和 @dynamic 語(yǔ)句的后面。在任何類中,init 都應(yīng)該直接放在 dealloc 方法的下面。
init 方法的結(jié)構(gòu)應(yīng)該像這樣:
- (instancetype)init {
self = [super init];
if (self != nil) {
// Custom initialization
}
return self;
}
字面量
每當(dāng)創(chuàng)建 NSString, NSDictionary, NSArray,和 NSNumber 類的不可變實(shí)例時(shí),應(yīng)使用 @"", @{}, @[], @()方式生成實(shí)例。要注意 nil 值不能傳給 NSArray 和 NSDictionary 字面量,這樣做會(huì)導(dǎo)致崩潰。
推薦:
NSArray *names = @[@"Brian", @"Matt", @"Chris", @"Alex", @"Steve", @"Paul"];
NSDictionary *productManagers = @{@"iPhone" : @"Kate", @"iPad" : @"Kamal", @"Mobile Web" : @"Bill"};
NSNumber *shouldUseLiterals = @YES;
NSNumber *buildingZIPCode = @10018;
反對(duì):
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 *buildingZIPCode = [NSNumber numberWithInteger:10018];
CGRect 函數(shù)
當(dāng)訪問(wèn)一個(gè) CGRect 的 x, y, width, height 時(shí),應(yīng)該使用CGGeometry 函數(shù)代替直接訪問(wèn)結(jié)構(gòu)體成員。蘋(píng)果的 CGGeometry 參考中說(shuō)到:
All functions described in this reference that take CGRect data structures as inputs implicitly standardize those rectangles before calculating their results. For this reason, your applications should avoid directly reading and writing the data stored in the CGRect data structure. Instead, use the functions described here to manipulate rectangles and to retrieve their characteristics.
推薦:
CGRect frame = self.view.frame;
CGFloat x = CGRectGetMinX(frame);
CGFloat y = CGRectGetMinY(frame);
CGFloat width = CGRectGetWidth(frame);
CGFloat height = CGRectGetHeight(frame);
反對(duì):
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;
宏
應(yīng)該盡量避免使用宏定義,除非沒(méi)有別的選擇,通常應(yīng)當(dāng)使用常量和枚舉,它們具有更強(qiáng)的類型檢查,而更加安全。
推薦:
static const CGFloat ThumbnailHeight = 50.0f;
反對(duì):
#define ThumbnailHeight 2.0f
枚舉類型
當(dāng)使用 enum 時(shí),建議使用新的基礎(chǔ)類型規(guī)范,因?yàn)樗哂懈鼜?qiáng)的類型檢查和代碼補(bǔ)全功能?,F(xiàn)在 SDK 包含了一個(gè)宏來(lái)鼓勵(lì)使用使用新的基礎(chǔ)類型 - NS_ENUM()
推薦:
typedef NS_ENUM(NSInteger, UIImageResizingMode) {
UIImageResizingModeTile,
UIImageResizingModeStretch,
};
位掩碼
當(dāng)用到位掩碼時(shí),使用 NS_OPTIONS 宏。
舉例:
typedef NS_OPTIONS(NSUInteger, UIViewAutoresizing) {
UIViewAutoresizingNone = 0,
UIViewAutoresizingFlexibleLeftMargin = 1 << 0,
UIViewAutoresizingFlexibleWidth = 1 << 1,
UIViewAutoresizingFlexibleRightMargin = 1 << 2,
UIViewAutoresizingFlexibleTopMargin = 1 << 3,
UIViewAutoresizingFlexibleHeight = 1 << 4,
UIViewAutoresizingFlexibleBottomMargin = 1 << 5
};
布爾
typedef signed char BOOL;
#define YES ((BOOL)1)
#define NO ((BOOL)0)
以上代碼片斷來(lái)自objc.h。永遠(yuǎn)不將布爾變量直接和 YES 進(jìn)行比較,因?yàn)?YES 被定義為 1,而 BOOL 可以多達(dá) 8 位。
if (isAwesome)
if (![someObject boolValue])
反對(duì):
if ([someObject boolValue] == NO)
if (isAwesome == YES)
單例
單例對(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;
}
其他 Objective-C 風(fēng)格指南
如果感覺(jué)我們的不太符合你的口味,可以看看這兩個(gè)風(fēng)格指南:Google Objective-C Style Guide 和 NYTimes Objective-C Style Guide,本指南也從它們那里獲得了很多直接的幫助和間接的啟發(fā)。