iOS代碼編程規(guī)范-根據(jù)項(xiàng)目經(jīng)驗(yàn)匯總

2016-05-19 23:27:10來源:開發(fā)者(KaiFaX)作者:蝴蝶之夢天使

與大家分享下我總結(jié)的iOS代碼編程規(guī)范,有不合適的請(qǐng)大家指出(最好能舉例說明為何不好,并給一個(gè)好的推薦)^_^

帶出幾十位從零開始學(xué)iOS的實(shí)習(xí)生或試用期的開發(fā)人員后,覺得真的是千人千面,每個(gè)人寫的代碼都風(fēng)格迥異,如果沒有一個(gè)文檔規(guī)范,每次都和新人進(jìn)行口頭的說教,大概自己是不用敲代碼了,所以吃了虧了就開始編寫iOS的編程規(guī)范。由于本人在寫iOS代碼前一直是C語言的開發(fā),所以很多規(guī)范都受C語言的影響。

與大家分享下我總結(jié)的編程規(guī)范,有不合適的請(qǐng)大家指出(最好能舉例說明為何不好,并給一個(gè)好的推薦)^_^

1.  指導(dǎo)原則

(1)首先是為人編寫程序,其次才是計(jì)算機(jī)。
軟件的生命周期貫穿產(chǎn)品的開發(fā),測試,生產(chǎn),用戶使用,版本升級(jí)和后期維護(hù)等過程,只有易讀,易維護(hù)的軟件代碼才具有生命力。

(2)保持代碼的簡明清晰,避免過分的編程技巧。
簡單是最美。不要過分追求技巧,否則會(huì)降低程序的可讀性。

(3)編程時(shí)首先達(dá)到正確性,其次考慮效率。
編程首先考慮的是滿足正確性,健壯性,可維護(hù)性,可移植性等質(zhì)量因素。

(4)編寫代碼時(shí)需要考慮到代碼的可測試性。
不可以測試的代碼是無法保障質(zhì)量的。實(shí)現(xiàn)設(shè)計(jì)功能的同時(shí),要提供可以測試、驗(yàn)證的方法。

(5)函數(shù)(方法)是為一特定功能而編寫,不是萬能工具箱。
方法是一個(gè)處理單元,是由特定功能的,所以應(yīng)該很好地規(guī)劃方法,不能是所有東西都放在一個(gè)方法里實(shí)現(xiàn)。

(6)鼓勵(lì)多注釋。
當(dāng)代碼有改動(dòng)時(shí),注釋一定要修改,并且不要添加多余或重復(fù)的注釋。

2.  布局

程序布局的目的是現(xiàn)實(shí)出程序良好的邏輯結(jié)構(gòu),提高程序的準(zhǔn)確性、連續(xù)性、可讀性、可維護(hù)性。統(tǒng)一的程序布局和編程風(fēng)格,有助于提高整個(gè)項(xiàng)目的開發(fā)質(zhì)量,提高開發(fā)效率,降低開發(fā)成本。

遵循統(tǒng)一的布局順序書寫頭文件和實(shí)現(xiàn)文件:

文件頭注釋
#import
文件內(nèi)部使用的宏
常量定義
文件內(nèi)部使用的數(shù)據(jù)類型
全局變量
本地變量
類定義/實(shí)現(xiàn)

(1)If、else、else if、for、while、do等語句自占一行,執(zhí)行語句不得緊跟其后,不論執(zhí)行語句有多少都要加{}。
“{”前面添加一個(gè)空格,緊跟語句后。方法(函數(shù))時(shí),“{”另起一行并獨(dú)        占一行書寫。
if ( numberA > numberB ) {
    return numberA;
}

(2)定義指針類型的變量,“*” 應(yīng)該放在變量前。
NSString *str1 = @"Hello World!";

(3)源代碼中關(guān)系較為緊密的代碼應(yīng)盡可能相鄰。
CGFloat fWidth;
CGFloat fLength;
CGFloat fHeight;

(4)禁止使用TAB鍵,必須使用空格進(jìn)行縮進(jìn),縮進(jìn)為4個(gè)空格。
在Xcode->Preferences->Text Editing->Indentation->Prefer indent using中,將值設(shè)置為Spaces。

(5)程序的分界符“{”和“}”在if、else、else if、for、while、do等語句時(shí),“{”前添加空格緊跟語句后。在方法(函數(shù))應(yīng)獨(dú)占一行并且位于同一列,同時(shí)與引用他們的語句對(duì)齊。“{}”之內(nèi)的代碼塊使用縮進(jìn)規(guī)則對(duì)齊。
- (void)dealloc
{
    // Do Something
}

if (isUpdated) {
        // Do Something
}

(6)相關(guān)的賦值語句等號(hào)對(duì)齊。
promotionsEntity.promotionImageStr   = activityItemDict[@"promotion_image"];
promotionsEntity.promotionIdNum      = activityItemDict[@"promotion_id"];
promotionsEntity.promotionNameStr    = activityItemDict[@"promotion_name"];
promotionsEntity.promotionColorStr   = activityItemDict[@"promotion_color"];

(7)在switch語句中,每一個(gè)case分支和default要用“{}”括起來,“{}”中的內(nèi)容需要縮進(jìn)。

(8)函數(shù)(方法)塊之間使用一個(gè)空行分隔。

(9)一元操作符如!、~、++、--、*、&、和[]、.、->、前后不加空格。
!bValue
~iValue
++iCount
*strSource
&fSum

(10)多元運(yùn)算符和他們的操作數(shù)之間至少需要一個(gè)空格。
fWidth = 5 + 5;
fLength = fWidth * 2;
fHeight = fWidth + fLength;

(11)關(guān)鍵字之后要留空格。“(”后和“)”前 不添加空格。
if、for、while等關(guān)鍵字之后應(yīng)留一個(gè)空格再跟左括號(hào)”(”。
if (0 == fWidth)
(12)方法名與形參不能留空格,返回類型與方法標(biāo)識(shí)符有一個(gè)空格。
方法名后緊跟”:”,然后緊跟形參,返回類型”(”與”-”之間有一個(gè)空格。
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender

(13)注釋符與注釋內(nèi)容之間要用一個(gè)空格進(jìn)行分割。
/* 設(shè)置Frame的值 */
// TO DO

(14)長表達(dá)式(超過80列)要在低優(yōu)先級(jí)操作符處拆分成新行,操作符放在新行之首(以便突出操作符)。拆分出的新行要進(jìn)行適當(dāng)?shù)乜s進(jìn),使排版整齊。
if ( 0 == fWidth
    || 0 < fLength )

(15)函數(shù)(方法)聲明時(shí),類型與名稱不允許分行書寫。
- (void)didReceiveMemoryWarning

(16)類中功能模塊以#pragma mark – 分割,上空兩行,下空一行
#pragma mark – UITextFieldDelegate

(17)方法實(shí)現(xiàn)時(shí),參數(shù)過長則每個(gè)參數(shù)用一行,以冒號(hào)對(duì)齊。
- (void)doSomethingWith:(NSString *)theFoo
                   rect:(CGRect)theRect
               interval:(CGFloat)theInterval
{

如果方法名比參數(shù)名短,則每個(gè)參數(shù)占用一行,至少縮進(jìn)4個(gè)字符,且為垂直對(duì)齊(非冒號(hào)對(duì)齊)。
- (void)short:(NSString *)theFoot
    longKeyword:(CGRect)theRect
    evenLongerkeyword:(float)theInterval
{
}

(18)方法調(diào)用沿用聲明方法的習(xí)慣。
在同一行
[self doSomethingWith:@"test" rect:self.view.frame interval:1.0f];
或 冒號(hào)對(duì)齊

[self doSomethingWith:@"test"
                 rect:self.view.frame
             interval:1.0f];

(19)@public 和 @private 使用單獨(dú)一行,且縮進(jìn)1個(gè)字符

(20)Protocals聲明中類型標(biāo)識(shí)符、代理名稱、尖括號(hào)間不留空格。
id<MyProtocalDelegate> delegate;

在類聲明中包含多個(gè)protocal,每個(gè)protocal占用一行,縮進(jìn)2個(gè)字符。
@interface CustomBackButtonViewController () <UITextFieldDelegate,
  MyProtocalDelegate,
  UITabBarControllerDelegate,
  UITabBarDelegate>

也可以與第一個(gè)對(duì)齊,保持清晰易讀
@interface ShopViewController () <UIGestureRecognizerDelegate,
                                  HXSClickEventDelegate,
                                  UITableViewDelegate,
                                  UITableViewDataSource>

如果并非所有方法都是必須得,使用@optional標(biāo)示。

(21)UIViewController.m的文件布局,不同變量和方法的先后順序:

<1>#import “LocationCustomButton.h”
最開始是導(dǎo)入需要使用到的其他class頭文件,頭文件按類型分類
// controller
#import “TextSelectionViewController.h"
// model
#import "PayPasswordUpdateModel.h"
#import "WalletModel.h"
// views
#import "PayPasswordAlertView.h"

<2>#define KEY_BANK_TAIL        @“bank_tail"
添加宏定義,將在文件中需要使用到的常量,字符串等用宏定義。

<3>@property (nonatomic, strong) NSArray *bankCardList;
property的屬性定義。不用將需要使用的methods聲明,在iOS7后Methods已經(jīng)不需要先聲明再使用了。

<4>- (void)viewDidLoad
#pragma mark - Life Cycle 添加生命周期的方法
- (void)viewWillAppear:(BOOL)animated
 - (void)viewDidAppear:(BOOL)animated
- (void)viewWillDisappear:(BOOL)animated
-(void)viewDidDisappear:(BOOL)animated
- (void)didReceiveMemoryWarning
- (void)dealloc

<5>#pragma mark - override
重載父類的方法
<6>#pragma mark - Intial Methods
初始化的方法,如
- (void)initialNavigationBar
- (void)initialTableView

<7>#pragma mark - Target Methods
點(diǎn)擊事件或通知事件

<8>#pragma mark - UITextFieldDelegate
Delegate的事件,將所有的delegate放在同一個(gè)pragma下

<9>#pragma mark - Setter Getter Methods
所有的property使用懶加載,并將setter或getter放在底部,不影響業(yè)務(wù)代碼的閱讀。

<10>#pragma mark - private method
私有方法的代碼盡量抽取創(chuàng)建公共class。

3.  注釋

(1)多行注釋采用”/ … /”, 單行注釋采用 “// …”.

(2)一般情況下,源程序有效注釋量必須在30%以上。
注釋語言不宜太多也不能太少,注釋語言必須準(zhǔn)確、易懂、簡潔。

(3)注釋應(yīng)與其描述的代碼相近,對(duì)代碼的注釋應(yīng)放在其上方或右方相鄰位置,不可放在下方,如放于上方則需要與其上面的代碼用空行隔開。

(4)注釋與所描述內(nèi)容進(jìn)行同樣地縮排。

(5)文件最前面的注釋,是保留了工程自動(dòng)生成的注釋,但是需要進(jìn)行如下修改:文件作者改為個(gè)人的名字,公司名為Insigma Hengtian software Ltd. 如:
//
//  ViewController.m
//  test
//
//  Created by ArthurWang on 14-5-7.
//  Copyright (c) 2014年 Insigma HengTian Software Ltd. All rights reserved.
//

(6)類、協(xié)議、結(jié)構(gòu)體注釋。如:
/*
 @class HTServerDatamanager
 @abstract 異步連接服務(wù)器管理類
 @discussion 異步請(qǐng)求服務(wù)器,接收到響應(yīng)后,通過回調(diào)把數(shù)據(jù)回傳到對(duì)象
 */

(7)成員方法、接口注釋。如:
/*
 @method  initWithTarget:selector:
 @abstract  類初始化函數(shù)
 @discussion  本類使用時(shí)必須調(diào)用此函數(shù)進(jìn)行初始化
 @param target 響應(yīng)回調(diào)對(duì)象
 @param selector  回調(diào)對(duì)象的selector
 @result   類對(duì)象
 */

4.  命名

(1)標(biāo)識(shí)符要采用英文單詞或其組合,便于記憶和閱讀,切忌使用漢語拼音來命名。
標(biāo)識(shí)符應(yīng)當(dāng)直觀且可以拼讀,可望文知意,英文單詞一般不要太復(fù)雜,用詞應(yīng)當(dāng)準(zhǔn)確。

(2)嚴(yán)格禁止使用連續(xù)的下劃線,下劃線也不能出現(xiàn)在標(biāo)識(shí)符頭或結(jié)尾。(實(shí)例變量及特殊用法除外)
CGFloat variable__name;
NSString *variale___name;

(3)程序中不要出現(xiàn)僅靠大小區(qū)分的相似的標(biāo)識(shí)符。
NSString *contentOfView;
NSString *ContentOfView;

(4)宏、常量名都要使用大寫字母,用下劃線‘_’分割單詞。
 #define URL_GAIN_QUOTE_LIST @"1/quotest"
#define URL_UPDATE_QUOTE_LIST @"1/quote/update"
#define URL_LOGIN   @"1/user/login”

(5)程序中局部變量不要與全局變量重名。
盡管局部變量和全局變量的作用域不同而不會(huì)發(fā)生語法錯(cuò)誤,但容易使人誤解。

(6)使用一致的前綴來區(qū)分變量的作用域。
g_  全局變量
s_  模塊內(nèi)靜態(tài)變量

(7)方法名用小寫字母開頭的單詞組合而成。
方法名力求清晰、明了、通過方法名就能夠判斷方法的主要功能。方法名中不同意義字段之間不要用下劃線連接,而要把每個(gè)字段的首字母大寫以示區(qū)分。
- (NSString *)descriptionWithLocale:(id)locale;

(8)盡量避免名字中出現(xiàn)數(shù)字編號(hào),如Value1, Vlaue2等,除非邏輯上的確需要編號(hào)。

(9)聲明實(shí)例變量,都采用property。
不在類聲明和實(shí)現(xiàn)的“{”與“}”之間聲明。
@interface LumberjackViewController ()
{
    NSArray *dataSource;  // 錯(cuò)誤:
}

(10)類名(及其category 和protocal)的首字母大寫,使用字母大寫的形式分割單詞。

5.  變量

變量、常量和數(shù)據(jù)類型是程序編寫的基礎(chǔ),是直接關(guān)系到程序設(shè)計(jì)的成敗。

(1)一個(gè)變量有且只有一個(gè)功能,盡量不要把一個(gè)變量用作多種用途。
一個(gè)變量只用來表示一個(gè)特定功能,不要把一個(gè)變量作多種用途。

(2)循環(huán)語句與判斷語句中,不允許對(duì)其它變量進(jìn)行計(jì)算與賦值。
錯(cuò)誤: if ( 100 > (fWidth = 50 * fLength) )

(3)宏定義中如果包含表達(dá)式或變量,表達(dá)式和變量必須用小括號(hào)括起來。
#define MY_MIN(A, B)   ((A)>(B)?(B):(A))

(4)宏名大寫字母

(5)對(duì)于全局變量通過統(tǒng)一的函數(shù)訪問。

(6)最好不要在語句塊內(nèi)聲明局部變量。

(7)系統(tǒng)常用類作實(shí)例變量聲明時(shí)加入后綴:
UIViewController: VC                      UIImage: Img
UIImageView:ImagView                   UIView:View
UILabel: Lbl                                    UIButton:Btn
UINavigationBar:Nbar                     UIToolbar:Tbar
UISearchBar:Sbar                            UITextField:TextField
UITextView:TextView                      NSArray:Array
NSMutableArray:Marray                  NSDictionary:Dict
NSMutableDictionary:Mdict             NSString:Str
NSMutableString:MStr                     NSSet:Set
NSMutableSet:Mset

(8)屬性聲明嚴(yán)把權(quán)限,對(duì)不需要外部修改的屬性使用readonly。

(9)NSString使用copy而非retain。
在ARC中NSString的使用Strong與Copy的效果一樣。

(10)CFType 使用@dynamic,禁止使用@synthesize

(11)除非必須,使用nonatomic。

(12)定義NSArray和NSDictionary使用泛型,提高代碼可讀性和健壯性。
NSArray<NSString *> *testArr = [NSArray arrayWithObjects:@"Hello", @"world", nil];
NSDictionary<NSString *, NSNumber *> *dic = @{@"key":@(1), @"age":@(10)};
在* 符號(hào)前面都添加一空格。

6.  表達(dá)式

表達(dá)式是語句的一部分,他們是不可分割的。

(1)一條語句只完成一個(gè)功能。
復(fù)雜的語句閱讀起來,難于理解,并容易隱含錯(cuò)誤。

(2)在表達(dá)式中使用括號(hào),使表達(dá)式的運(yùn)算順序更清晰。
由于將運(yùn)算符的優(yōu)先級(jí)與結(jié)合律熟記是比較困難的,為了防止產(chǎn)生歧義并提高可讀性,即使不加括號(hào)時(shí)運(yùn)算順序不會(huì)改變,也應(yīng)當(dāng)用括號(hào)確定表達(dá)式的操作順序。
if ( (( 0 == iYear%4 ) && ( 0 != iYear%100 )) || ( 0 == iYear%400 ) )

(3)避免表達(dá)式中的附加功能,不要編寫太復(fù)雜的復(fù)合表達(dá)式。
錯(cuò)誤:int iResult = iYear++-++iMonth+iDay++;
(4)不可將布爾變量和邏輯表達(dá)式直接與YES、NO或則1、0進(jìn)行比較。
if (isSuccess)   //真
if (!isSuccess)  //假

(5)在條件判斷語句中,當(dāng)整型變量與0比較時(shí),不可模仿布爾變量的風(fēng)格,應(yīng)當(dāng)將整型變量用“==”或“!=”直接與0比較。
if (0 == iYear)
if ( 0 != iMonth )

(6)應(yīng)當(dāng)將指針變量用“==”或“!=”與nil比較。
指針變量的零值是“空”(即nil),nil的值與0相同,但是兩者含義不同。
if ( nil == strName )

(7)在switch語句中,每一個(gè)case分支必須使用break結(jié)尾,最后一個(gè)分支必須是default分支。
避免漏掉break語句造成程序錯(cuò)誤,同時(shí)保持程序簡潔。對(duì)于多個(gè)分支相同處理的情況可以共用一個(gè)break,但是要用注釋加以說明。

(8)不可在for循環(huán)內(nèi)修改循環(huán)變量,防止for循環(huán)失去控制。

(9)循環(huán)嵌套次數(shù)不大于3次。

(10)do while 語句和while語句僅使用一個(gè)條件。

(11)如果循環(huán)體內(nèi)存在邏輯判斷,并且循環(huán)次數(shù)很大,宜將邏輯判斷移到循環(huán)體的外面。

(12)for語句的循環(huán)控制變量的取值采用“半開半閉區(qū)間”寫法。

這樣做更能適應(yīng)數(shù)組的特點(diǎn),數(shù)組的下標(biāo)屬于一個(gè)“半開半閉區(qū)間”。
int iMax[1000];
for (int i = 0; i < 1000; i++)
{
    NSLog(@"%d", iMax[i]);
}

(13)將int值轉(zhuǎn)換為BOOL時(shí)應(yīng)特別小心。

(14)OC中,BOOL被定義為unsigned char,這意味著除了YES(1)和NO(0)外它還可以是其他值。禁止將int直接轉(zhuǎn)換為BOOL。

(15)將整型值轉(zhuǎn)換為BOOL的方法:使用三元運(yùn)算符返回YES/NO,或使用&&,||。

(16)BOOL、_BOOL和bool之間的轉(zhuǎn)換是安全的,但是BOOL和Boolean間的轉(zhuǎn)換不是安全的,所以將Boolean堪稱整型值。

(17)在OC中,只允許使用BOOL。

7.  函數(shù)

(1)方法不能為多個(gè)目的服務(wù)。
一個(gè)方法一個(gè)功能。

(2)在接口中應(yīng)該盡量少使用外部定義的類型(減少耦合)。

(3)避免函數(shù)有太多的參數(shù),參數(shù)個(gè)數(shù)盡量控制在5個(gè)以內(nèi)。
如果參數(shù)的確比較多,不妨把這些參數(shù)定義成一個(gè)結(jié)構(gòu)(或一個(gè)類)。

(4)對(duì)于有返回值的函數(shù)(方法),每一個(gè)分支都必須有返回值。
為了保證對(duì)被調(diào)用函數(shù)返回值的判斷,有返回值的函數(shù)中都每一個(gè)退出點(diǎn)都需要有返回值。
(5)對(duì)輸入?yún)?shù)的正確性和有效性進(jìn)行檢查。
很多程序錯(cuò)誤和崩潰是由非法參數(shù)引起的。

(6)防止將函數(shù)(方法)的參數(shù)作為工作變量。
將函數(shù)的參數(shù)作為工作變量,有可能錯(cuò)誤地改變參數(shù)內(nèi)容。對(duì)必須改變的參數(shù),最好先用局部變量代之,最后再將該局部變量的內(nèi)容賦給該參數(shù)。

(7)函數(shù)(方法)體的規(guī)模不能太大,盡量控制在200行之內(nèi)。
冗長的函數(shù)不利于調(diào)試,可讀性差。

(8)禁止直接調(diào)用NSObject的類方法+new,也不要在子類中重載它。使用alloc和init方法。

(9)創(chuàng)建對(duì)象時(shí)盡量使用autorelease,創(chuàng)建臨時(shí)對(duì)象時(shí),盡量同時(shí)在同一行中autorelease掉,而非使用單獨(dú)的release語句。

(10)Dealloc的順序要與變量聲明的順序相同。
這樣有利于review代碼。
如果dealloc中調(diào)用其他方法來release變量,將被release的變量以注釋的形式標(biāo)注清楚。
先release自身成員變量,再調(diào)用父類dealloc方法。

8.  頭文件

(1)申明成員類,應(yīng)該引用該類申明,而不是包含該類的頭文件。
@class MyViewController;
@interface ViewController : UIViewController
{
    MyViewController *_myViewController;
}

(2)共同的接口、結(jié)構(gòu)體、常量和數(shù)據(jù)類型要定義在同一個(gè)頭文件里。

(3)使用#import引入OC和OC++頭文件,使用#include引入c和c++頭文件。

9.  可靠性

為保證代碼的可靠性,編程時(shí)請(qǐng)遵循如下基本原則,優(yōu)先級(jí)遞減:

  • 正確性
  • 穩(wěn)定性
  • 可測試性
  • 規(guī)范/可讀性
  • 全局效率
  • 局部效率
  • 個(gè)人表達(dá)方式/個(gè)人方便性

(1)防止內(nèi)存操作越界
內(nèi)存操作主要是指對(duì)數(shù)組、指針、內(nèi)存地址等得操作,內(nèi)存操作越界是軟件系統(tǒng)主要錯(cuò)誤之一,后果往往非常嚴(yán)重,引起崩潰。

(2)當(dāng)變量釋放后,需要將變量置為nil。
避免因?yàn)橐爸羔樢鸬某绦虮罎ⅰ?/p>

(3)變量在使用前應(yīng)初始化,防止未初始化的變量被引用。
引用未初始化的變量,會(huì)引起程序的崩潰。

(4)指針類型變量必須初始化為nil。

(5)指針不要進(jìn)行復(fù)雜的邏輯或算術(shù)操作。
通過復(fù)雜的邏輯或算術(shù)操作后,指針的位置就很難確定。

(6)減少指針和數(shù)據(jù)類型的強(qiáng)制類型轉(zhuǎn)化。
強(qiáng)制類型轉(zhuǎn)化如果類型強(qiáng)轉(zhuǎn)錯(cuò)誤會(huì)引起崩潰。

(7)對(duì)變量進(jìn)行賦值時(shí),必須對(duì)其值進(jìn)行合法性檢查,防止越界等現(xiàn)象發(fā)生。

(8)非初始化方法中的alloc操作之前必須要nil判斷。

(9)在編寫派生類的賦值時(shí),主要不要忘記對(duì)基類的成員變量重新賦值。
- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

(10)私有方法應(yīng)該在實(shí)現(xiàn)文件中申明。
@interface ViewController ()
- (void)login;
@end

10.  斷言

斷言是對(duì)某種假設(shè)條件進(jìn)行檢查,可以快速發(fā)現(xiàn)并定位軟件文件,同時(shí)對(duì)系統(tǒng)錯(cuò)誤進(jìn)行自動(dòng)報(bào)警。

(1)整個(gè)軟件系統(tǒng)應(yīng)該采用統(tǒng)一的斷言。
assert(str);

(2)正式軟件產(chǎn)品中應(yīng)把斷言及其它的調(diào)測代碼去掉。
加快軟件運(yùn)行速度。

11. 其他
(1) 避免過多直接使用立即數(shù)。
應(yīng)該都使用宏定義,采用立即數(shù)不容易理解含義并容易出錯(cuò)。

(2) 枚舉第一個(gè)成員要賦初始值。

(3) addObject之前要非空判斷。

(4) release版本代碼去掉NSLog打印,除了保留異常分支的NSLog。

(5) 禁止在代碼中直接寫死字符串資源,必須要用字符串ID替代。
應(yīng)該考慮多語言國際化,盡量使用NSLocalizedStringFromTable實(shí)現(xiàn)對(duì)字符串ID的引用。

(6) 對(duì)于框架設(shè)計(jì),邏輯層盡量與UI層分離,降低耦合度。

(7) delegate對(duì)象使用assign,禁止使用retain。
因?yàn)閞etain會(huì)引起導(dǎo)致循環(huán)索引導(dǎo)致內(nèi)存泄露,并且對(duì)類型的內(nèi)存泄露無法被Instrument發(fā)現(xiàn),極難調(diào)試。

(8) Controller獨(dú)立于View和Controller。
不要在View相關(guān)的類中添加過多的業(yè)務(wù)邏輯代碼,這讓代碼的可重用性很差。Controller負(fù)責(zé)業(yè)務(wù)邏輯代碼,且Controller的代碼與View盡量無關(guān)。

(9)init方法和dealloc方法是最常用的方法,所以將他們放在類實(shí)現(xiàn)的開始位置。

(10) 使用空格將相同的變量、屬性對(duì)齊,使用換行分組。

// END

關(guān)鍵詞:iOS編程規(guī)范