iOS代碼規(guī)范

方法聲明與定義:

1.星號前統(tǒng)一要求需要輸入空格

2.方法體左大括號于方法名的右側(cè)

3.-或者+與返回類型之間需要有空格。參數(shù)列表中,只有參數(shù)之間有空格。

-?(void)doSomethingWithString:(NSString?*)theString?{

...

}

如果一行有非常多的參數(shù),更好的方式是將每個(gè)參數(shù)單獨(dú)拆成一行。如果使用多行,將每個(gè)參數(shù)前的冒號對齊。

-?(void)doSomethingWith:(GTMFoo?*)theFoo

rect:(NSRect)theRect

interval:(float)theInterval?{

...

}

協(xié)議:

尖括號所包括的協(xié)議名稱與前面的類型標(biāo)識之間不應(yīng)該有空格

@interface?MyProtocoledClass?:?NSObject?{

@private?id?delegate;

}

方法名:

方法名應(yīng)該讀起來就像句子,這表示你應(yīng)該選擇與方法名連在一起讀起來通順的參數(shù)名。

convertPoint:fromRect:

replaceCharactersInRange:withString:

訪問器方法應(yīng)該與他們getting的的成員變量的名字一樣,但不應(yīng)該以get作為前綴。

例如:

-?(id)getDelegate;??//?AVOID

-?(id)delegate;?????//?GOOD

變量名:

要為變量起一個(gè)描述性的名字。不要擔(dān)心浪費(fèi)列寬,若包含兩個(gè)以上單詞的命名應(yīng)該使用駝峰命名方式,因?yàn)樽屝碌拇a閱讀者立即理解你的代碼更重要。

錯(cuò)誤的命名:

int?w;

int?nerr;

int?nCompConns;

UIButton*settingsButton;

tix?=?[[NSMutableArray?alloc]?init];

obj?=?[someObject?object];

p?=?[network?port];

正確的命名:

int?numErrors;

int?numCompletedConnections;

tickets?=?[[NSMutableArray?alloc]?init];

userInfo?=?[someObject?object];

port?=?[network?port];

星號應(yīng)緊貼變量名稱表示指向變量的指針,比如:

正確用法:

NSString *text;

不當(dāng)用法:

NSString* text;

NSString * text;

方法調(diào)用:

方法調(diào)用時(shí),所有參數(shù)應(yīng)該在同一行

[myObject?doFooWith:arg1?name:arg2?error:arg3];

或者每行一個(gè)參數(shù),以冒號對齊

[myObject?doFooWith:arg1

name:arg2

error:arg3];

[UIViewanimateWithDuration:1.0

animations:^{

// something

}

completion:^(BOOL?finished) {

// something

}];

異常:

每個(gè)@標(biāo)簽應(yīng)該有獨(dú)立的一行,在@與{}之間需要有一個(gè)空格。@catch與被捕捉到的異常對象的聲明之間也要有一個(gè)空格。

@try?{

foo();

}

@catch?(NSException?*ex)?{

bar(ex);

}

@finally?{

baz();

}

條件語句的編寫:

1.為避免錯(cuò)誤,條件語句體必須使用大括號,即便語句體中的語句可以不必使用大括號(比如只有一行語句)。常見的錯(cuò)誤包括在不使用大括號的情況下添加第二行語句,以為它屬于if語句的一部分。此外,更可怕的事情是,如果條件語句中的代碼行被注釋,則本不術(shù)語條件語句的下一行代碼將變成條件語句的一部分。此外,這種編碼風(fēng)格和所有其它條件語句均保持一致.

例如:

恰當(dāng)用法:

if(!error) {

returnsuccess;

}

不當(dāng)用法:

if(!error)

returnsuccess;

不當(dāng)用法2:

if(!error)returnsuccess;

2. 編寫括號內(nèi)的判斷語句時(shí),為避免手誤演變成賦值操作,一般將常量或nil放置在左邊

例如:

if(nil == self.dataList)?{

}

if(0 == theCount) {

}

Case語句

除非編譯器強(qiáng)制要求,括號在 case 語句里面是不必要的。但是當(dāng)一個(gè) case 包含了多行語句的時(shí)候,需要加上括號。

switch (condition) {

case 1:

// ...

break;

case 2: {

// ...

// Multi-line example using braces

break;

}

case 3:

// ...

break;

default:

// ...

break;

}

有時(shí)候可以使用 fall-through 在不同的 case 里面執(zhí)行同一段代碼。一個(gè) fall-through? 是指移除 case 語句的 “break” 然后讓下面的 case 繼續(xù)執(zhí)行。

switch (condition) {

case 1:

case 2:

// code executed for values 1 and 2

break;

default:

// ...

break;

}

常量

相對字符串字面量或數(shù)字,我們更推薦適用常量。應(yīng)使用static方式聲明常量,而非使用#define的方式來定義宏。

例如:

恰當(dāng)用法:

static?NSString?*?const?NYTAboutViewControllerCompanyName?=@"The New York Times Company";

static?const?CGFloat NYTImageThumbnailHeight?=50.0;

不當(dāng)用法:

#define CompanyName @"The?New?York Times Company"

#define thumbnailHeight 2

枚舉類型

在使用enum的時(shí)候,推薦適用最新的fixed underlying type(WWDC 2012 session 405- Modern Objective-C)規(guī)范,因?yàn)樗邆涓鼜?qiáng)的類型檢查和代碼完成功。

例如:

typedefNS_ENUM(NSInteger, NYTAdRequestState) {

NYTAdRequestStateInactive,

NYTAdRequestStateLoading

};

布爾變量

因?yàn)閚il將被解析為NO,因此沒有必要在條件語句中進(jìn)行比較。永遠(yuǎn)不要將任何東西和YES進(jìn)行直接比較,因?yàn)閅ES被定義為1,而一個(gè)BOOL變量可以有8個(gè)字節(jié)。

例如:

恰當(dāng)用法:

if(!someObject) {

}

不當(dāng)用法:

if(someObject==nil) {

}

以下是BOOL變量的使用:

恰當(dāng)用法:

if(isAwesome)

if(![someObject boolValue])

不當(dāng)用法:

if([someObject boolValue]==NO)

if(isAwesome==YES)// Never do this.

三目運(yùn)算

僅當(dāng)使用該運(yùn)算子可以讓代碼顯得更清晰易懂時(shí)方可使用三元運(yùn)算子,切三目運(yùn)算體內(nèi)應(yīng)均為運(yùn)算結(jié)果,不然被忽略的錯(cuò)誤比較容易產(chǎn)生。 更多情況下應(yīng)使用條件語句。使用類似if的條件語句對多種條件進(jìn)行判斷通常要更容易理解,或使用實(shí)例變量。

恰當(dāng)用法:

result=a>b?x:y;

不當(dāng)用法:

result=a>b?x=c>d?c:d:y;

CGRect函數(shù)

當(dāng)需要獲取一個(gè)CGRect矩形的x,y,width,height屬性時(shí),應(yīng)使用CGGeometry函數(shù),而非直接訪問結(jié)構(gòu)體成員。

例如:

恰當(dāng)用法:

CGRect frame=self.view.frame;

CGFloat x=CGRectGetMinX(frame);

CGFloat y=CGRectGetMinY(frame);

CGFloat width=CGRectGetWidth(frame);

CGFloat height=CGRectGetHeight(frame);

不當(dāng)用法:

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;

單例

在創(chuàng)建單例對象的共享實(shí)例時(shí),應(yīng)使用線程安全模式,獲取單例對象類方法命名使用sharedXXXX。

例如:

(instancetype)sharedInstance{

staticidsharedInstance?=nil;

staticdispatch_once_tonceToken;

dispatch_once(&onceToken,?^{

sharedInstance?=?[[self alloc] init];

});

return?sharedInstance;

}

美化代碼:

空格

方法的大括號和其他的大括號(if/else/switch/while?等) 總是在同一行開始,在新起一行結(jié)束。

推薦:

if?(user.isHappy) {

//Do something

}

else?{

//Do something else

}

不推薦:

if?(user.isHappy)

{

//Do something

}?else?{

//Do something else

}

換行

self.productsRequest = [[SKProductsRequest?alloc]?initWithProductIdentifiers:productIdentifiers];

一個(gè)像上面的長行的代碼在第二行以一個(gè)間隔(2個(gè)空格)延續(xù)

self.productsRequest = [[SKProductsRequest?alloc]

initWithProductIdentifiers:productIdentifiers];

利用代碼塊

一個(gè) GCC 非常模糊的特性,以及 Clang 也有的特性是,代碼塊如果在閉合的圓括號內(nèi)的話,會返回最后語句的值

NSURL?*url = ({

NSString?*urlString = [NSString?stringWithFormat:@"%@/%@", baseURLString, endpoint];

[NSURL?URLWithString:urlString];

});

所有的變量都在代碼塊中,也就是只在代碼塊的區(qū)域中有效,這意味著可以減少對其他作用域的命名污染。

Pragma Mark

#pragma mark -?是一個(gè)在類內(nèi)部組織代碼并且?guī)椭惴纸M方法實(shí)現(xiàn)的好辦法。 我們建議使用?#pragma mark -?來分離:

#pragma mark?- View Lifecycle (View 的生命周期)

- (void)viewDidLoad {?/* ... */?}

- (void)viewWillAppear:(BOOL)animated {?/* ... */?}

- (void)didReceiveMemoryWarning {?/* ... */?}

#pragma mark?- Custom Accessors (自定義訪問器)

- (void)setCustomProperty:(id)value {?/* ... */?}

- (id)customProperty {?/* ... */?}

建立委托者和數(shù)據(jù)源使用“weak關(guān)鍵字”

@property?(nonatomic,?weak)?id delegate;

@property?(nonatomic,?weak)?id dataSource;

默認(rèn)情況下,委托對象需要實(shí)現(xiàn) protocol 的方法??梢杂聾required?和?@optional?關(guān)鍵字來標(biāo)記方法是否是必要的還是可選的。

@protocol?ZOCSignUpViewControllerDelegate?

@required

- (void)signUpViewController:(ZOCSignUpViewController *)controller?didProvideSignUpInfo:(NSDictionary?*);

@optional

- (void)signUpViewControllerDidPressSignUpButton:(ZOCSignUpViewController *)controller;

@end

對于可選的方法,委托者必須在發(fā)送消息前檢查委托是否確實(shí)實(shí)現(xiàn)了特定的方法(否則會 crash):

if?([self.delegate?respondsToSelector:@selector(signUpViewControllerDidPressSignUpButton:)]) {

[self.delegate?signUpViewControllerDidPressSignUpButton:self];

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • iOS編程規(guī)范0規(guī)范 0.1前言 為??高產(chǎn)品代碼質(zhì)量,指導(dǎo)廣大軟件開發(fā)人員編寫出簡潔、可維護(hù)、可靠、可 測試、高效...
    iOS行者閱讀 4,611評論 21 35
  • 代碼規(guī)范 1. h文件代碼 類功能說明注釋。屬性說明注釋。方法說明注釋。類名加前綴,避免命名空間沖突. 2. m文...
    ValienZh閱讀 1,499評論 0 2
  • 對于我而言,為數(shù)不多取悅自己的方式就是,發(fā)現(xiàn)一片新的大陸,或者將自己的屋子收拾成自己想要的樣子。 controll...
    senpaiLi閱讀 359評論 1 1
  • 一、命名規(guī)范 1、統(tǒng)一要求含義清楚,盡量做到不需要注釋也能了解其作用,若做不到,就加注釋,使用全稱,不使用縮寫。 ...
    Untils閱讀 622評論 0 0
  • 芥末烤貝殼/原創(chuàng) 親愛的,我會在未來遇到你,并且愛上你,我們會許下度過一生的承諾,從此執(zhí)子之手與子偕老。 ——引子...
    芥末烤貝殼閱讀 493評論 0 0

友情鏈接更多精彩內(nèi)容