object-c 編碼規(guī)范與指導(dǎo)
文檔版本
版本號 | 修改時間 | 修改內(nèi)容 | 修改人 |
---|
概述
對于任何工程項目來說别渔,統(tǒng)一的施工標準都是保證工程質(zhì)量的重要因素惨奕∨置耄堪稱當(dāng)今人類最抽象、最復(fù)雜的工程—軟件工程惋增,自然更加不能例外。高品質(zhì)改鲫、易維護的軟件開發(fā)離不開清晰嚴格的編碼規(guī)范诈皿。本文檔詳細描述object-C軟件開發(fā)過程中的編碼規(guī)范。本規(guī)范也適用于所有在文檔中出現(xiàn)的源碼像棘。
文件結(jié)構(gòu)
所有iphone的源文件均必須包含一個規(guī)范的說明稽亏,說明包含了該文件的名稱、功能概述缕题、作者截歉、版權(quán)和版本歷史信息等內(nèi)容。文件頭和函數(shù)的說明的格式為:
1.文件頭說明
/*fileName
======================================================================
模塊名 :<模塊名稱>
文件名 :<文件名>
實現(xiàn)功能:<描述該文件實現(xiàn)的主要功能>
作者 :<作者部門和姓名>
版本 :<當(dāng)前版本號>
創(chuàng)建日期:
備注 :<其它說明>
修改日期:<日期格式:yyyy-mm-dd>
修改人 :<修改人>
修改內(nèi)容:<修改內(nèi)容>
======================================================================
fileName*/
2.方法說明
/**
* <#Description#>
*
* @param task <#task description#>
* @param arrange <#arrange description#>
*
* @created by 謝躦 on 2015-01-21 09:30:19
*/
3.頭文件的引用說明
在h文件中引用其他類用@class fileName
烟零;
在m文件中引用其他類都用#import “fileName.h
”
4.文件的組織結(jié)構(gòu)
參考 coding ios 客戶端源碼規(guī)范
├── Coding_iOS
│ ├── Models:數(shù)據(jù)類
│ ├── Views:視圖類
│ │ ├── CCell:所有的CollectionViewCell都在這里
│ │ ├── Cell:所有的TableViewCell都在這里
│ │ └── XXX:ListView(項目瘪松、動態(tài)、任務(wù)锨阿、討論宵睦、文檔、代碼)和InputView(用于聊天和評論的輸入框)
│ ├── Controllers:控制器墅诡,對應(yīng)app中的各個頁面
│ │ ├── Login:登錄頁面
│ │ ├── RootControllers:登錄后的根頁面
│ │ ├── MeSetting:設(shè)置信息頁面
│ │ └── XXX:其它頁面
│ ├── Images:app中用到的所有的圖片都在這里
│ ├── Resources:資源文件
│ ├── Util:一些常用控件和Category壳嚎、Manager之類
│ │ ├── Common
│ │ ├── Manager
│ │ ├── OC_Category
│ │ └── ObjcRuntime
│ └── Vendor:用到的一些第三方類庫,一般都有改動
│ ├── AFNetworking
│ ├── AGEmojiKeyboard
│ ├── ASProgressPopUpView
│ ├── ActionSheetPicker
│ ├── FontAwesome+iOS
│ ├── MJPhotoBrowser
│ ├── MLEmojiLabel
│ ├── NSDate+Helper
│ ├── NSStringEmojize
│ ├── PPiAwesomeButton
│ ├── QBImagePickerController
│ ├── RDVTabBarController
│ ├── SMPageControl
│ ├── SVPullToRefresh
│ ├── SWTableViewCell
│ ├── UMENG
│ ├── UMessage_Sdk_1.1.0
│ ├── XGPush
│ ├── XTSegmentControl
│ └── iCarousel
└── Pods:項目使用了[CocoaPods](http://code4app.com/article/cocoapods-install-usage)這個類庫管理工具
命名規(guī)則
如果想要有效的管理一個稍微復(fù)雜一點的體系末早,針對其中事物的一套統(tǒng)一烟馅、帶層次結(jié)構(gòu)、清晰明了的命名準則就是必不可少而且非常好用的工具然磷。
活躍在生物學(xué)焙糟、化學(xué)、軍隊样屠、監(jiān)獄穿撮、黑社會缺脉、恐怖組織等各個領(lǐng)域內(nèi)的大量有識先輩們都曾經(jīng)無數(shù)次地以實際行動證明了以上公理的正確性。除了上帝(設(shè)它可以改變世間萬物的秩序)以外悦穿,相信沒人有實力對它不屑一顧攻礼。
在軟件開發(fā)這一高度抽象而且十分復(fù)雜的活動中,命名規(guī)則的重要性更顯得尤為突出栗柒。一套定義良好并且完整的礁扮、在整個項目中統(tǒng)一使用的命名規(guī)范將大大提升源代碼的可讀性和軟件的可維護性。
在引入細節(jié)之前瞬沦,先說明一下命名規(guī)范的整體原則:
-
同一性:
在編寫一個子模塊或派生類的時候太伊,要遵循其基類或整體模塊的命名風(fēng)格,保持命名風(fēng)格在整個模塊中的同一性逛钻。 -
標識符組成:
標識符采用英文單詞或其組合僚焦,應(yīng)當(dāng)直觀且可以拼讀,可望文知意曙痘,用詞應(yīng)當(dāng)準確芳悲。 -
最小化長度和最大化信息量原則:
在保持一個標識符意思明確的同時,應(yīng)當(dāng)盡量縮短其長度边坤。 -
避免過于相似:
不要出現(xiàn)僅靠大小寫區(qū)分的相似的標識符名扛,例如i
與I
,function
與Function
等等茧痒。 -
避免在不同級別的作用域中重名:
程序中不要出現(xiàn)名字完全相同的局部變量和全局變量肮韧,盡管兩者的作用域不同而不會發(fā)生語法錯誤,但容易使人誤解旺订。 -
正確命名具有互斥意義的標識符:
用正確的反義詞組命名具有互斥意義的標識符惹苗,如:minValueInteger
和maxValueInteger
,getName()
和setName()
等
5. h耸峭,m桩蓉,nib文件名命名
除了異常類等個別情況(不希望被用戶看作一個普通的、正常的類之情況)外劳闹,iphone的h院究,m,nib文件名命名應(yīng)該遵循以下準則:
(1) h本涕,m业汰,nib文件名命名的名稱都要以大寫字母開頭;
(2) 如果是一般的視圖控制器菩颖,則后面加上ViewController样漆,即h,m晦闰,nib
文件名的名稱仿效分別為:
***ViewController.h
***ViewController.m
***ViewController.xib
(3)如果是自定義的視圖類放祟,則后面加上對應(yīng)的類型鳍怨,
UITableViewCell 簡寫為 Cell,UICollectionViewCell 簡寫為CCell
h跪妥,m鞋喇,nib文件名的名稱仿效分別為:
***View.h、
***View.m眉撵、
***View.xib侦香;
***Cell.h、
***Cell.m纽疟、
***Cell.xib罐韩;
***CCell.h、
***CCell.m污朽、
***CCell.xib散吵;
6. 變量
(1)所有變量名命名的名稱都要以小寫字母開頭。
(2)類中定義變量名稱:其主要格式為***+對象類所在的名稱
膘壶,如給UITextFiled
命名错蝴,則要寫成***TextField
洲愤、如valueTextFiled
颓芭、titleTextField
等,相應(yīng)的UILabel
的命名有valueLabel
柬赐、titleLabel
等亡问,UITableView
則要寫成valueTableView
等。其規(guī)則也同樣適用于NSArray肛宋、NSMutableDictonary
等所有類型州藕;
另外,如果當(dāng)前變量是自己類中使用酝陈,則要在后面加上下劃線床玻,如valueArray_等,而在屬性中定義時用valueArray沉帮。
(3)全局變量全部以單詞_global
開頭锈死,以類型結(jié)尾,如_global***TextField
穆壕、_global***String
等待牵。
(4)成員變量。在變量前面加上下劃線_
如
UIButon * _cancelButton;
(5)其中NSMutaleArray喇勋、NSMutableDictonary與NSArray缨该、NSDictonary的結(jié)尾相同,分別為Array及Dict川背,不做區(qū)分贰拿。
7. 方法
(1)所有方法名命名的名稱都要以小寫字母開頭蛤袒,要求語義完整清晰,不要亂用簡寫壮不。
(2) 在ViewController中汗盘,一個控件可能有多個事件 如果是事件的名稱,則要先以對象名稱加上對象的事件询一,如
UIButton *nameButton;
#program mark - Event
//默認情況下 EventTouchUpInside 我們簡寫成 Pressed
- (IBAction) nameButtonPressed:(id)sender;
//EventTouchDown
- (IBAction) nameButtonTouchDown:(id)sender;
(3) Action隐孽。 如果是在一個視圖類中,一個控件的事件相對于這個視圖類來說只是視圖類的一個事件健蕊,則不需要以控件對像名稱加上對像事件命名菱阵。 而是根據(jù)視圖類來命名。
@interface AbstractActionSheetPicker : NSObject
@end
UIBarButtonItem *sysDoneButton = [self createButtonWithType:UIBarButtonSystemItemDone target:self
action:@selector(actionPickerDone:)];
UIBarButtonItem *sysCancelButton = [self createButtonWithType:UIBarButtonSystemItemCancel target:self
action:@selector(actionPickerCancel:)];
- (IBAction)actionPickerDone:(id)sender
{
}
- (IBAction)actionPickerCancel:(id)sender
{
}
8. 宏
宏全部用大寫缩功,并且用必要的下劃線分開晴及,如
#define NAME_VALUE @"dddd"
#define MAXSIZE 30
9. 常量
常量用字母 k 開頭, 如
static const NSUInteger kUsernameRow = 0;
10. 代碼風(fēng)格
代碼風(fēng)格與版式代碼風(fēng)格的重要性怎么強調(diào)都不過分嫡锌。一段稍長一點的無格式代碼基本上就是不可讀的虑稼。 先來看一下這方面的整體原則:
-
空行的使用
空行起著分隔程序段落的作用∈颇荆空行得體(不過多也不過少)將使程序的布局更加清晰蛛倦。空行不會浪費內(nèi)存啦桌,雖然打印含有空行的程序是會多消耗一些紙張溯壶,但是值得。所以不要舍不得用空行甫男。 這里不做規(guī)定且改,視自己的風(fēng)格而定 -
語句與代碼行
一行代碼只做一件事情,如只定義一個變量板驳,或只寫一條語句又跛。這樣的代碼容易閱讀,并且方便于寫注釋若治。
“if”慨蓝、“for”、“while”直砂、“try”菌仁、“catch”等語句自占一行,執(zhí)行語句不得緊跟其后静暂。不論執(zhí)行語句有多少都要加 “{ }” 济丘。這樣可以防止書寫和修改代碼時出現(xiàn)失誤。 -
縮進和對齊
程序的分界符 “{” 和 “}” 的格式如下所示:
while(1){
//statement
for(int i=0;i<=n;i++){
//statement
}
}
以上風(fēng)格是約定風(fēng)格,而下面風(fēng)格則不提倡摹迷。
while(1)
{
//statement
for(int i=0;i<=n;i++)
{
//statement
}
}
“{ }” 之內(nèi)的代碼塊在 “{” 右邊一個制表符(4個半角空格符疟赊,直接按鍵盤上的Tab鍵來進行控制)處左對齊。
最大長度
代碼行最大長度宜控制在80個字符以內(nèi)峡碉。代碼行不要過長近哟,否則眼睛看不過來,也不便于打印鲫寄。不過此規(guī)則可以視情況適當(dāng)放寬吉执。空格的使用
關(guān)鍵字之后要留空格。象NSInteger等關(guān)鍵字之后至少要留一個空格地来;
其余的不做要求戳玫,如for語句里面的幾條語句、&&未斑、||等咕宿。修飾符的位置
為便于理解,應(yīng)當(dāng)將修飾符 “*” 和 “&” 緊靠變量蜡秽,例如NSString *testString
府阀、NSArray *testArray
等注釋
注釋的位置應(yīng)與被描述的代碼相鄰,可以放在代碼的上方或右方芽突,不可放在下方试浙。
邊寫代碼邊注釋,修改代碼同時修改相應(yīng)的注釋诉瓦,以保證注釋與代碼的一致性川队。不再有用的注釋要刪除力细。
注釋應(yīng)當(dāng)準確睬澡、易懂,防止注釋有二義性眠蚂。錯誤的注釋不但無益反而有害煞聪。
當(dāng)代碼比較長,特別是有多重嵌套時逝慧,應(yīng)當(dāng)在一些段落的結(jié)束處加注釋昔脯,便于閱讀笛臣。對于業(yè)務(wù)邏輯云稚,常用的枚舉數(shù)據(jù),或者代碼對應(yīng)的參數(shù)一定要有說明,如
/**
* 設(shè)置類型
*
* @param type 類型 0 公有沈堡,1 私有
*
* @created by 謝躦 on 2015-01-21 18:47:24
*/
- (void)setType:(NSInteger)type
{
if(0 == type){
//當(dāng)類型為公有的時候
...
}else if (1 == type){
//當(dāng)類型為私有的時候
...
}
}
11. h文件組織
類 interface h文件中分別依次列出屬性静陈,方法。
#import <UIKit/UIKit.h>
@interface DateilViewController : UIViewController
{
//變量
NSString *_dataString;
}
//屬性
@property (nonatomic, strong) NSDictionary *supplyDateilDict;
@property (nonatomic, strong) NSMutableArray *supplyArray;
//方法
- (void)handleData;
- (void)createView;
@end
協(xié)議 protocol ,依次列出 @required
,@optional
和
@protocol UITableViewDataSource<NSObject>
@required
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
// Row display. Implementers should *always* try to reuse cells by setting each cell's reuseIdentifier and querying for available reusable cells with dequeueReusableCellWithIdentifier:
// Cell gets various attributes set automatically based on table (separators) and data source (accessory views, editing controls)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
@optional
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView; // Default is 1 if not implemented
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section; // fixed font style. use custom view (UILabel) if you want something different
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section;
// Editing
// Individual rows can opt out of having the -editing property set for them. If not implemented, all rows are assumed to be editable.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath;
// Moving/reordering
// Allows the reorder accessory view to optionally be shown for a particular row. By default, the reorder control will be shown only if the datasource implements -tableView:moveRowAtIndexPath:toIndexPath:
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath;
// Index
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView; // return list of section titles to display in section index view (e.g. "ABCD...Z#")
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index; // tell table which section corresponds to section title/index (e.g. "B",1))
// Data manipulation - insert and delete support
// After a row has the minus or plus button invoked (based on the UITableViewCellEditingStyle for the cell), the dataSource must commit the change
// Not called for edit actions using UITableViewRowAction - the action's handler will be invoked instead
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath;
// Data manipulation - reorder / moving support
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath;
@end
12. m文件組織
/*Class 的生命周期
* Class 生命周期回調(diào)方法放在最前面
*/
#pragma mark - Lifecircle
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
}
- (void)viewDidLoad
{
}
- (void)viewWillAppear:(BOOL)animated
{
}
- (void)viewDidDisappear:(BOOL)animated
{
}
- (void)didReceiveMemoryWarning
{
}
- (void)dealloc
{
}
/* 所有的控件事件放在生命周期后面
* 包括 Event ,Action,Notifation
* 如果是相近的方法用program mark 分類。排在一起鲸拥。
*/
#pragma mark - Event
- (void)backAction
{
}
- (void)selectTabbarButton:(UIButton *)sender
{
}
+ (void)reachabilityChanged:(NSNotification *)note
{
}
#pragma mark KeyBoardNotify
- (void)keyboardWillChange:(NSNotification *)note
{
}
- (void)keyboardShowNotify:(NSNotification *)note
{
}
//鍵盤隱藏調(diào)整界面
- (void)keyboardHideNotify:(NSNotification *)note
{
}
/*其它方法分為兩部分拐格,
* 第一部分是數(shù)據(jù)模型操作相關(guān)的方法
* 第二部分為視圖,控件相關(guān)操作
*/
#pragma mark - Fouction
#pragma mark - HandleModal
- (void)getSupplyDateilData
{
}
// 時間轉(zhuǎn)換
- (NSString *)showTimeWithValue:(NSTimeInterval)time
{
}
//添加一個安排
- (void)addArrange
{
}
#pragma mark HandleView
- (void)creatDateilView
{
}
// 顯示土地信息
- (void)creatDateilInformationView
{
}
- (void)createAdvertisementView
{
}
/*
* 其它協(xié)議刑赶,委托捏浊,數(shù)據(jù)源方法沒有固定順序,用到了就加到后面
*/
#pragma mark -UITableViewDataSource
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
}
#pragma mark -UITableViewDelegate
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
}
--