- 說兩句
項(xiàng)目結(jié)構(gòu)和代碼風(fēng)格的重要性對(duì)于一個(gè)團(tuán)隊(duì)和項(xiàng)目來說不言而喻纬朝。首先項(xiàng)目結(jié)構(gòu)清晰合理砾肺,方便產(chǎn)品的快速迭代以及提高團(tuán)隊(duì)的開發(fā)效率碟贾;其次統(tǒng)一的規(guī)范可以促進(jìn)團(tuán)隊(duì)合作,降低維護(hù)成本悼院,以及有助于代碼審查伤为,減少bug處理。
以下也只是列舉了個(gè)大概,只要養(yǎng)成了良好的代碼習(xí)慣绞愚,自然而然就會(huì)不斷的要求自己叙甸,提高自己。
一位衩、項(xiàng)目結(jié)構(gòu)
結(jié)構(gòu)如圖所示
結(jié)構(gòu)說明
- Classes
- Extensions - 擴(kuò)展類
- Common - 項(xiàng)目之間可公用方法
- Global - 項(xiàng)目?jī)?nèi)公共方法裆蒸、變量、宏定義
- Manager - 網(wǎng)絡(luò)請(qǐng)求類糖驴、數(shù)據(jù)庫(kù)操作類僚祷、緩存操作類
- Model - 模型
- ViewModel - 視圖模型(視情況需要增加)
- Views - 視圖(根據(jù)功能模塊分出Item)
- Constrollers - 控制器(根據(jù)功能模塊分出Item)
- Category - 分類
- Frameworks - 系統(tǒng)的框架
- Tookis - 引用的第三方
二、Objective-C代碼規(guī)范
目錄
- 代碼結(jié)構(gòu)
- 空格
- 注釋
- 命名
- 方法
- 變量
- 常量
- 枚舉
- 單例模式
代碼結(jié)構(gòu)
//ViewController 生命周期
#pragma mark - Lifecycle
- (void)viewDidLoad {}
- (void)viewWillAppear:(BOOL)animated {}
- (void)didReceiveMemoryWarning {}
//通知事件
#pragma mark - Notificaion
- (void)keyboardWillAppear:(NSNotification *)aNotification {}
//手勢(shì)方法
#pragma mark - Gesture
- (void)backgroundViewTapGesture:(UITapGestureRecognizer *)sender {}
//按鈕以及其他控件Change事件
#pragma mark - Action
- (IBAction)registerButtonHandler:(id)sender {}
//代理事件
#pragma mark - UITextField Delegate
#pragma mark - UITableView Delegate & DataSource
//私有方法
#pragma mark - Private
- (void)initUI {} //UI初始化方法
- (void)loadData {} //加載數(shù)據(jù)方法
- (void)displayInfo {} //加載完UI顯示數(shù)據(jù)方法
- (void)privateMethod {} //其他私有業(yè)務(wù)邏輯等方法
//共有方法
#pragma mark - Public
- (void)publicMethod {} //外部調(diào)用方法
空格
- 縮進(jìn)使用4個(gè)空格贮缕,確保在Xcode偏好設(shè)置來設(shè)置辙谜。
- 方法大括號(hào)和其他大括號(hào)(if/else/switch/while 等.)總是在同一行語句打開但在新行中關(guān)閉。
- 成員變量空格位置
@property (copy, nonatomic) NSString *userName;
- 方法空格位置
//- 后面 and 參數(shù)名之間 and 第一個(gè)大括號(hào)前 需要一個(gè)空格
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 2;
}
注釋
當(dāng)需要注釋時(shí)感昼,注釋應(yīng)該用來解釋這段特殊代碼為什么要這樣做装哆。任何被使用的注釋都必須保持最新或被刪除。
一般都避免使用塊注釋定嗓,因?yàn)榇a盡可能做到自解釋蜕琴,只有當(dāng)斷斷續(xù)續(xù)或幾行代碼時(shí)才需要注釋。例外:這不應(yīng)用在生成文檔的注釋
命名
Apple命名規(guī)則盡可能堅(jiān)持蜕乡,特別是與這些相關(guān)的memory management rules(NARC)奸绷。
長(zhǎng)的,描述性的方法和變量命名是好的层玲。
變量的命名使用駝峰式号醉。
- 控件命名必須加控件后綴
應(yīng)該:
UIButton *settingsButton;
不應(yīng)該:
UIButton *setBut;
- 常見變量命名
@property (copy, nonatomic) NSString *userName;
//數(shù)組用List、s辛块、array后綴,推薦List
@property (strong, nonatomic) NSMutableArray *orderList;
//Bool類型用is前綴
@property (assign, nonatomic) BOOL isLogin;
- 靜態(tài)變量加前綴
應(yīng)該:
static NSTimeInterval const RWTTutorialViewControllerNavigationFadeAnimationDuration = 0.3;
不應(yīng)該:
static NSTimeInterval const fadetime = 1.7;
- Model類命名
使用項(xiàng)目前綴线椰,如"KB"-> KBUser
方法
在方法簽名中卿捎,應(yīng)該在方法類型(-/+ 符號(hào))之后有一個(gè)空格。在方法各個(gè)段之間應(yīng)該也有一個(gè)空格(符合Apple的風(fēng)格)惧眠。在參數(shù)之前應(yīng)該包含一個(gè)具有描述性的關(guān)鍵字來描述參數(shù)览濒。
"and"這個(gè)詞的用法應(yīng)該保留。它不應(yīng)該用于多個(gè)參數(shù)來說明,就像initWithWidth:height
以下這個(gè)例子:
應(yīng)該:
- (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;
不應(yīng)該:
-(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.
變量
- 變量名稱采用英文命名且命名所見即所得旬蟋,明確變量的意義匆浙。不得存在拼音或含糊不清的英文表達(dá)
- 屬性特征要寫明
@property (copy, nonatomic) NSString *userName;
@property (strong, nonatomic) NSMutableArray *orderList;
@property (assign, nonatomic) BOOL isLogin;
常量
常量首選內(nèi)聯(lián)字符串字面量或數(shù)字软能,因?yàn)槌A靠梢暂p易重用并且可以快速改變而不需要查找和替換。常量應(yīng)該聲明為 static 常量而不是 #define 了罪,除非非常明確地要當(dāng)做宏來使用难礼。
推薦:
static NSString * const NYTAboutViewControllerCompanyName = @"The New York Times Company";
static const CGFloat NYTImageThumbnailHeight = 50.0;
反對(duì):
#define CompanyName @"The New York Times Company"
#define thumbnailHeight 2
- UserDefault Key常量
//UserDefalut Key
//使用前綴 kUDKey標(biāo)明
static NSString * const kUDKeyPrivacySwitchState = @"kUDKeyPrivacySwitchState";
- Notification Key常量
//Notification Key
//使用小寫k開頭、以及Notification結(jié)尾
static NSString * const kAddDiarySucceedNotificaiton = @"kAddDiarySucceedNotificaiton";
枚舉
使用NS_ENUM進(jìn)行枚舉蛾茉,加上前綴
typedef NS_ENUM(NSInteger, KBUserSex) {
KBUserSexMan = 1, //男
KBUserSexWoman = 2, //女
};
單例模式
單例對(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;
}