一、命名規(guī)則
1、總則
-
簡(jiǎn)潔
簡(jiǎn)單明了,盡量使用全拼
應(yīng)該: setBackgroundColor
不應(yīng)該:setBkgdColor
當(dāng)然,我們也會(huì)有一些常用的縮略詞,比如 info 代表 Information等(持續(xù)補(bǔ)充)
- 一致性
作用相同,或者在表達(dá)同一件事時(shí),統(tǒng)一命名。
比如位置存儲(chǔ)信息 location,不要再出來(lái)place表示位置的情況。
2、命名方法
遵守駝峰命名法,類名首字母大寫,方法名和屬性首字母小寫(首字母為縮略詞,如ZJB時(shí)亦使用小寫,ZJBTableviewModel定義時(shí)使用z j bTableViewModel)
1、類名規(guī)范 (Class)
類名必須使用名詞,如果一個(gè)類名內(nèi)含多個(gè)單詞,那么各個(gè)單詞第一個(gè)字母大寫,后續(xù)字母小寫,起伏呈駝峰狀。給類名命名時(shí),必須保證準(zhǔn)確、簡(jiǎn)潔且容易理解。盡量使用完整單詞,避免使用縮寫詞(除了大家公認(rèn)的);
要求:
-
選擇有意義的名字,能快速地傳達(dá)該類的用途。類名需要加前綴,前綴一般為:“工程關(guān)鍵詞”+“項(xiàng)目關(guān)鍵詞”,我們現(xiàn)在工程中目前可暫不使用“工程關(guān)鍵詞”,但新建的都要遵循新標(biāo)準(zhǔn),如
ZJBBusListViewController ZJBBusOrederDetailsViewController //我們?cè)瓉?lái)的類名可不加上“工程關(guān)鍵詞” BusListViewController BusOrederDetailsViewController除VC和View外,自己封裝的公共的基礎(chǔ)組件統(tǒng)一加上ZJB前綴,區(qū)分第三方,如
ZJBThirdAppService ZJBEmptyView 當(dāng)要區(qū)別委托類時(shí),需細(xì)分是delegate還是protocol,在委托類的后面加上“Delegate”或“Protocol”。如:SceneryQueryBLLDelegate;
實(shí)體類區(qū)分Request和Response。如:RequestGetSceneryList、ResponseGetSceneryList;
2、方法名規(guī)范(Method)
方法名應(yīng)該以小寫字母開頭,并混合駝峰格式。每個(gè)具名參數(shù)也應(yīng)該以小寫字母開頭 方法名應(yīng)盡量讀起來(lái)就像句子,這表示你應(yīng)該選擇與方法名連在一起讀起來(lái)通順的參數(shù)名。第二個(gè)及以后參數(shù)不要"and"
- (CGPoint)convertPoint:(CGPoint)point fromView:(nullable UIView *)view;
- (void)replaceCharactersInRange:(NSRange)range withString:(NSString *)str;
//正確:
- (instancetype)initWithWidth:(float)width height:(float)height;
//不好:
- (id)initWithWidth:(float)width andHeight:(float)height;
3、變量名規(guī)范
變量必須起有意義的名字,使其他組員可以很容易讀懂變量所代表的意義。第一個(gè)單詞為類型首字母且小寫,其他單詞首字母大寫。自定義類型可隨意命名前綴;
| 類型 | 前綴 | 舉例 |
|---|---|---|
| int | i | iNumber |
| float | f | fHeight |
| BOOL | b | bNearBy |
| NSUInteger | i | iTicketCount |
| NSString | s | sCityName |
| NSMutaArray/NSArray | arr | arrData |
| NSMutaDictionary/NSDictionary | dic | dicData |
| short | sht | shtNumber |
| Long/long | lng | lngNumber |
| Double/double | dbl | dblNumber |
4、控件名規(guī)范
控件命名前綴或者后綴增加通用符號(hào),優(yōu)點(diǎn)是易識(shí)別,未包含的控件使用全稱或自定義,通俗易懂。
| 類型 | 前綴/后綴 | 舉例 |
|---|---|---|
| UILabel | lbl* | lblName |
| UIButton | btn* | btnTip |
| UITextField | txf* | txfName |
| UIImage | img* | imgHead |
| UIImageView | Imgv* | imgvHead |
| UIView | *View | headView |
| UIViewController | *VC | homeVC |
| UIScrollView | *ScrollView | bannerScrollView |
| UITableView | *TableView | mainTableView |
| UITableViewCell | cell* | cellHybridTest |
| UITextView | *TextView | userWriteTextView |
| UIWebView | *WebView | customWebView |
| NSLayoutConstraint | *Constraint | sliderViewLeadingConstraint |
| UIMapView | *MapView | busStationMapView |
5、枚舉名規(guī)范(Enum)
枚舉名同類名規(guī)則,加前綴,前綴一般為:“工程關(guān)鍵詞”+“項(xiàng)目關(guān)鍵詞”,大駝峰命名;枚舉值,大駝峰命名
typedef NS_ENUM(NSInteger, ZJBBusRequestStatusType) {
ZJBBusRequestStatusType_Default = 0,//默認(rèn)狀態(tài)未請(qǐng)求
ZJBBusRequestStatusType_Executing,//請(qǐng)求進(jìn)行中
ZJBBusRequestStatusType_Success,//請(qǐng)求成功
ZJBBusRequestStatusType_Fail,//請(qǐng)求失敗
ZJBBusRequestStatusType_Cancel//請(qǐng)求取消
};
多用枚舉控制多態(tài),減少bool值等去判斷的情況,增加可讀性
6、常量名規(guī)范
以const修飾一個(gè)常量,一般是寫在.h文件中,然后將.h的頭文件加入預(yù)編譯pch文件中;私有的寫在.m文件中。以小寫字母k開頭,后面單詞遵循"駝峰原則"命名。例如:
static const NSTimeInterval kTimeDuration = 0.5;
static const float kMaxHeight = 100.f;
static NSString * const kAppName = @"巴士管家";
定義常量時(shí):多用類型常量,少用#define預(yù)處理指令;宏定義沒有類型,有被重復(fù)定義風(fēng)險(xiǎn),影響工程編譯速度。
//建議用
static NSString * const kConst = @"Hello";
static const CGFloat kWidth = 10.0;
//代替
#define kConst @"Hello"
#define kWidth 10.0
當(dāng)定義對(duì)外公開的常量的時(shí)候,我們一般使用如下定義
//Test.h
extern NSString * const kClassNameconst;
//Test.m
NSString * const kClassNameconst = @"hello";
7、通知名規(guī)范
用類名做前綴,Notification做后綴;如:
UIApplicationDidEnterBackgroundNotification
UIApplicationWillEnterBackgroundNotification
8、塊名規(guī)范(Block)
模塊關(guān)鍵詞 + 功能名詞 + "Block";例:
typedef void (^CityListRequestBlock)(TCTNetworkError * _Nullable error);
typedef void (^CityListSearchResultBlock)(NSMutableArray *cityList);
9、圖片命名規(guī)范
-
基本要求:
- 文件名必須全小寫
- 采用下劃線命名法
- 采用單詞全拼,或者大家公認(rèn)無(wú)岐義的縮寫(比如:nav,bg,btn等)
-
基本規(guī)范:"模塊_類別_功能_狀態(tài).png"
對(duì)于靜態(tài)的模塊功能頁(yè)面,按照 "模塊_類別_功能_狀態(tài).png" 這樣的規(guī)則命名。如“bus_icon_info.png”
- 模塊:即項(xiàng)目或公共模塊名
- 類別:參照3的 基本名詞命名
- 功能:即按鈕作用
- 狀態(tài):如按鈕會(huì)有select等狀態(tài),無(wú)狀態(tài)可省略
-
基本名詞命名:
bg (backgrond) 背景 nav(navbar) 導(dǎo)航欄 tab(tabbar) 標(biāo)簽欄 btn(button) 按鈕 img(image) 圖片 icon 圖標(biāo) line 線條 logo 標(biāo)識(shí) bar 進(jìn)度條 arrow 箭頭 不限于此,只是列出一些常用的,只要認(rèn)可的都行。
-
狀態(tài)常用命名:
selected 選中 disabled 無(wú)法點(diǎn)擊 highlight 點(diǎn)擊時(shí)高亮 default 默認(rèn) normal 一般 pressed 按下 slide 滑動(dòng) 不限于此,只是列出一些常用的,只要認(rèn)可的都行。
二、代碼格式化
1、代碼結(jié)構(gòu)
代碼中vc或者View遵循這樣的代碼結(jié)構(gòu),方便閱讀。
#pragma mark - life cycle
#pragma mark - private methods
#pragma mark - delegate
#pragma mark - event response
#pragma mark - getters and setters
建議多使用“#pragma mark”,方便閱讀代碼,5個(gè)部分順序可以變化,但是除了上述5個(gè)帶“-”分割線以外,其他不要帶,不然造成過(guò)多的分割線,只需要這5個(gè)部分的分割線即可。明確用唯一的分割來(lái)區(qū)分開5個(gè)部分!
2、語(yǔ)法糖
應(yīng)該使用可讀性更好的語(yǔ)法糖來(lái)構(gòu)造 NSArray , NSDictionary 等數(shù)據(jù)結(jié)構(gòu),避免使用冗長(zhǎng)的 alloc,init 方法。
NSArray *animals = @[@"dog", @"pig", @"you"];
Dictionary *dict = @{@"animal":@"tiger", @"phone":@"iPhone 6"};
NSString *dog = animals[0];
NSString *iphone = dict[@"phone"];
3、方法聲明和調(diào)用
- 聲明
-或者+和返回類型之間須使用一個(gè)空格,括號(hào)要同行并有一個(gè)空格。方法應(yīng)該像這樣:
- (void)doSomethingWithString:(NSString *)theString {
...
}
如果函數(shù)名字太長(zhǎng),參數(shù)過(guò)多,則可以換行并用冒號(hào)對(duì)齊,像這樣:
- (void)doSomethingWith:(GTMFoo *)theFoo
rect:(NSRect)theRect
interval:(float)theInterval {
...
}
注:比較特殊且少見的情況,當(dāng)?shù)谝粋€(gè)關(guān)鍵字比其它的短時(shí),要保證下一行至少有4個(gè)空格的縮進(jìn),對(duì)齊關(guān)鍵字,像這樣:
- (void)shortWord:(NSString *)sShortWord
longKeyword:(NSString *)sTheRect
evenLongerKeyword:(float)fTheInterval {
...
}
- 調(diào)用
參數(shù)較少且代碼較短的可以放在一行,如:
[myObject doFooWith:arg1 name:arg2 error:arg3];
參數(shù)較多,代碼較長(zhǎng)的換行,冒號(hào)對(duì)其,如:
[myObject doFooWith:arg1
name:arg2
error:arg3];
4、對(duì)象初始化
不要使用new方法。盡管很多時(shí)候能用 new 代替 alloc init 方法,但這可能會(huì)導(dǎo)致調(diào)試內(nèi)存時(shí)出現(xiàn)不可預(yù)料的問(wèn)題。 Cocoa 的規(guī)范就是使用 alloc init 方法,使用 new 會(huì)讓一些讀者困惑。
5、conditions(條件語(yǔ)句)
條件語(yǔ)句要格外注意空格和括號(hào)等寫法,便于閱讀
-
if
//正確 if (condition) { // Do something } else { // Do something else } if (!error) { return success; } //不正確 if (!error) return success; if (!error) return success;
-
switch
switch (condition) { case 0: { ... } break; case 1: { .... } break; default: { ... } break; }
6、category(分類)
建議使用類別來(lái)簡(jiǎn)明地劃分功能,并且應(yīng)該通過(guò)命名來(lái)描述該功能。命名要明確體現(xiàn)其功能,不要搞通用。
//建議
@interface UIButton (SettingStyle)
@interface NSNumber (ChineseNumber)
//不建議
@interface UIAlertController (Custom)
@interface NSDate (Utility)
category中的方法名建議帶有標(biāo)識(shí)前綴,比如zjb_XXX method,防止無(wú)意中覆蓋同名方法,可能是系統(tǒng)方法。
//建議
@interface UIButton (SettingStyle)
- (void)zjb_setButtonBackGroundImage:(UIImage *)image;
@end
//不建議
@interface UIButton (SettingStyle)
- (void)setButtonBackGroundImage:(UIImage *)image;
@end
7、CGRect
在訪問(wèn)CGRect的x、y、寬度或高度時(shí),代碼必須使用CGGeometry函數(shù),而不是直接訪問(wèn)struct成員。從蘋果的CGGeometry參考:
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);
//不建議
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;
8、單例模式
寫單例的時(shí)候可能出現(xiàn)別人init了這個(gè)類,創(chuàng)建一個(gè)新的對(duì)象,要保證永遠(yuǎn)都只為單例對(duì)象分配一次內(nèi)存空間,寫法如下:
#import "Singleton.h"
static Singleton* _instance = nil;
@implementation Singleton
+(instancetype)shareInstance
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [[super allocWithZone:NULL] init];
});
return _instance;
}
+(id)allocWithZone:(struct _NSZone *)zone
{
return [Singleton shareInstance];
}
-(id)copyWithZone:(struct _NSZone *)zone
{
return [Singleton shareInstance];
}
@end
三、重要原則
1、私有變量和屬性
私有變量和屬性都定義到.m文件中,包括從xib中拖拉的控件。.h文件中只能有對(duì)外提供的參數(shù)和api的定義
2、Public API 要盡量簡(jiǎn)潔
公有接口要設(shè)計(jì)的簡(jiǎn)潔,滿足核心的功能需求就可以了。不要設(shè)計(jì)很少會(huì)被用到,但是參數(shù)極其復(fù)雜的 API 。如果要定義復(fù)雜的方法,使用類別或者類擴(kuò)展。