iOS代碼規(guī)范

運(yùn)算符

  1. 一元運(yùn)算符與變量之間沒有空格
!bValue
~iValue
++iCount
*strSource
&fSum
  1. 二元運(yùn)算符與變量之間必須有空格
fWidth = 5 + 5;
fLength = fWidth * 2;
fHeight = fWidth + fLength;
for(int i = 0; i < 10; i++)

變量

1.變量名必須使用駝峰格式,自定義類,協(xié)議使用大駝峰

SFHomePageViewController

2.對(duì)象等局部變量使用小駝峰

NSString *personName = @"";

3.變量的名稱必須同時(shí)包含功能與類型

UIButton *addButton //添加按鈕
UILabel *nameLabel //名字標(biāo)簽
NSArray *nameArray //名字?jǐn)?shù)組
NSDictionary *productDict //產(chǎn)品字典

常量

1.常量以相關(guān)類名作為前綴

static const NSTimeInterval YZDLoginAnimateViewFadeOutTime = 0.4;

2.對(duì)外公開某個(gè)常量,如通知

//.h文件
extern NSString *const YZDLoginOutNotification;
//.m文件
static NSString * const YZDLoginOutNotification = @"YZDLoginOutNotification";

枚舉

  1. 使用NS_ENUM進(jìn)行定義
  2. 對(duì)于一些狀態(tài) 選項(xiàng)的使用枚舉
    盡量少用根據(jù)數(shù)字判斷狀態(tài)少用字符串 數(shù)字判斷狀態(tài)
typedef NS_ENUM(NSInteger, DQGameInfoDisplayType) {
    DQGameInfoDisplayTypeDefault = 0,
    DQGameInfoDisplayTypeMatch = 1, //比賽
    DQGameInfoDisplayTypeEvent = 2, //對(duì)應(yīng)節(jié)目
};

  1. 宏、常量名都要使用大寫字母,用下劃線‘_’分割單詞
#define URL_GAIN_QUOTE_LIST @"/v1/quote/list"
#define URL_UPDATE_QUOTE_LIST @"/v1/quote/update"
#define URL_LOGIN  @"/v1/user/login”
  1. 宏定義中如果包含表達(dá)式或變量盾致,表達(dá)式和變量必須用小括號(hào)括起來
#define MY_MIN(A, B)  ((A)>(B)?(B):(A))
  1. 開頭用k標(biāo)識(shí),比如Cell的重用字符荣暮,k+cell的名稱+identifier
#define kGBHomeItemTableViewCellIdentifier = @"kGBHomeItemTableViewCellIdentifier"

屬性

  1. 屬性的關(guān)鍵字推薦按照原子性庭惜,讀寫,內(nèi)存管理的順序排列
@property (nonatomic, readwrite, copy) NSString *name;
@property (nonatomic, readwrite, strong) UIView *headerView;

方法

  1. 方法名中不應(yīng)使用and渠驼,而且簽名要與對(duì)應(yīng)的參數(shù)名保持高度一致
- (instancetype)initWithWidth:(CGFloat)width height:(CGFloat)height;
  1. 方法實(shí)現(xiàn)時(shí)蜈块,如果參數(shù)過長(zhǎng)鉴腻,則令每個(gè)參數(shù)占用一行,以冒號(hào)對(duì)齊
- (void)doSomethingWithFoo:(NSString *)theFoo
                      rect:(CGRect)theRect
                  interval:(CGFloat)theInterval {
   //Implementation
}
  1. 大括號(hào)開始與行尾
void function(param1,param2) {
 
}

  1. 類文件名要見名知意
  • Model類名以Model結(jié)尾
YZDUserModel
  • 自定義視圖命名以View結(jié)尾
YZDTabIndexHeaderView
  • 視圖控制器命名以ViewController結(jié)尾
YZDTabIndexViewController
  1. init && dealloc
// 將 dealloc 方法放在實(shí)現(xiàn)文件的最前面
- (void)dealloc {
    // 釋放注冊(cè)的通知和KVO的監(jiān)聽
}
- (instancetype)init { 
    self = [super init]; // call the designated initializer 
    if (self) { 
        // Custom initialization 
    } 
    return self; 
}
  1. 類的頭文件中盡量少引用其他頭文件
    有時(shí)百揭,類A需要將類B的實(shí)例變量作為它公共API的屬性爽哎。這個(gè)時(shí)候,我們不應(yīng)該引入類B的頭文件器一,而應(yīng)該使用向前聲明(forward declaring)使用class關(guān)鍵字课锌,并且在A的實(shí)現(xiàn)文件引用B的頭文件。祈秕,這么做的優(yōu)點(diǎn):
  • 不在A的頭文件中引入B的頭文件渺贤,就不會(huì)一并引入B的全部?jī)?nèi)容,這樣就減少了編譯時(shí)間请毛。
  • 可以避免循環(huán)引用:因?yàn)槿绻麅蓚€(gè)類在自己的頭文件中都引入了對(duì)方的頭文件志鞍,那么就會(huì)導(dǎo)致其中一個(gè)類無法被正確編譯。
// EOCPerson.h
#import
 
@class EOCEmployer;
 
@interface EOCPerson : NSObject
 
@property (nonatomic, copy) NSString *firstName;
@property (nonatomic, copy) NSString *lastName;
@property (nonatomic, strong) EOCEmployer *employer;//將EOCEmployer作為屬性
 
@end
 
// EOCPerson.m
#import "EOCEmployer.h"

但是個(gè)別的時(shí)候方仿,必須在頭文件中引入其他類的頭文件:
主要有兩種情況:

  • 該類繼承于某個(gè)類固棚,則應(yīng)該引入父類的頭文件。
  • 該類遵從某個(gè)協(xié)議仙蚜,則應(yīng)該引入該協(xié)議的頭文件此洲。而且最好將協(xié)議單獨(dú)放在一個(gè)頭文件中
  1. 頭文件.h
  • 方法的參數(shù)在一排顯示
  • 方法之間保留一行
  • 第一個(gè)方法和property保留空行
  • 最后一個(gè)方法和@end保留空行
@interface ViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>

@property (nonatomic, strong) UIWindow *window;
@property (nonatomic, copy) NSString *name;

- (void)testName;

- (void)testAge;

@end
  1. 實(shí)現(xiàn)文件.m
  • 引用頭文件的順序
#import <AVFoundation/AVFoundation.h>
#import <Mantle/Mantle.h>
#import "SFUserStatus.h"
  • 類的布局順序
- (void)dealloc

#pragma mark - Life Cycle Methods
 
#pragma mark - Override Methods
 
#pragma mark - Network Methods
 
#pragma mark - Target Methods
 
#pragma mark - Public Methods
 
#pragma mark - Private Methods
 
#pragma mark - Delegate 
 
#pragma mark - Lazy Loads

分類

  1. 分類添加的方法需要添加前綴和下劃線
@interface NSMutableDictionary (DQSafetyCheck)

/**
 *  空值保護(hù) key,value為空時(shí)防止crash
 *
 *  @param anObject object
 *  @param aKey     key
 */
- (void)dq_setSafeObject:(id)anObject forKey:(id)aKey;

@end

if語(yǔ)句

  1. 必須列出所有分支(窮舉所有的情況),而且每個(gè)分支都必須給出明確的結(jié)果委粉。推薦這樣寫
var hintStr;
if (count < 3) {
    hintStr = "Good";
} else {
    hintStr = "";
}

不推薦這樣寫

var hintStr;
if (count < 3) {
   hintStr = "Good";
}
  1. 不要使用過多的分支呜师,要善于使用return來提前返回錯(cuò)誤的情況
    推薦這樣寫:
- (void)someMethod { 
    if (!goodCondition) {
        return;
    }
    //Do something
}

不推薦這樣寫:

- (void)someMethod { 
    if (goodCondition) {
        //Do something
    }
}
  1. 條件過多,過長(zhǎng)的時(shí)候應(yīng)該換行
if (condition1() && 
    condition2() && 
    condition3() && 
    condition4()) {
  // Do something
}

Switch語(yǔ)句

  1. 每個(gè)分支都必須用大括號(hào)括起來贾节,每個(gè)case都要添加break關(guān)鍵字汁汗,避免出現(xiàn)fall-through
switch (integer) {  
    case 1: {
        // ...  
        break; 
     } 
    case 2: {  
        // ...  
      break;  
    }  
    case 3: {
        // ...  
      break; 
    }
    default: {
        // ...  
      break; 
    }
}
  1. 使用枚舉類型時(shí),不能有default分支栗涂, 除了使用枚舉類型以外碰酝,都必須有default分支
RWTLeftMenuTopItemType menuType = RWTLeftMenuTopItemMain;  
switch (menuType) {  
    case RWTLeftMenuTopItemMain: {
        // ...  
        break; 
    }
    case RWTLeftMenuTopItemShows: {
        // ...  
        break; 
    }
    case RWTLeftMenuTopItemSchedule: {
        // ...  
        break; 
    }
}

函數(shù)

  1. 一個(gè)函數(shù)的長(zhǎng)度不要太長(zhǎng)
  2. 一個(gè)函數(shù)只做一件事(單一原則)
  3. 對(duì)于有返回值的函數(shù)(方法),每一個(gè)分支都必須有返回值
int function() {
    if (condition1) {
        return count1
    } else if (condition2) {
        return count2
    } else {
       return defaultCount
    } 
}
  1. 對(duì)輸入?yún)?shù)的正確性和有效性進(jìn)行檢查戴差,參數(shù)錯(cuò)誤立即返回
void function(param1,param2) {
      if (param1 is unavailable) {
           return;
      }
 
      if (param2 is unavailable) {
           return;
      }
 
     //Do some right thing
}

代理、block

  1. 代理铛嘱,合理的使用optional暖释,required關(guān)鍵字
  2. 向代理、block發(fā)送消息時(shí)需要判斷其是否實(shí)現(xiàn)該方法
if ([self.delegate respondsToSelector:@selector(signUpViewControllerDidPressSignUpButton:)]) { 
     [self.delegate signUpViewControllerDidPressSignUpButton:self]; 
}

字符串墨吓、數(shù)組球匕、字典

取值一定要注意類型、非空帖烘、越界等的判斷亮曹,防止崩潰等問題

  • 字符串
//判斷字符串是否是字符串,是否是null,一般從網(wǎng)絡(luò)獲取
static inline BOOL verifiedString(id strlike) {
    if (strlike && ![strlike isEqual:[NSNull null]] && [[strlike class] isSubclassOfClass:[NSString class]] && ((NSString *) strlike).length > 0) {
        return YES;
    } else {
        return NO;
    }
}
// 用法
if (verifiedString(urlString)) {
     // dosomething
}
  • 數(shù)組
//判斷是否是有效數(shù)組照卦,一般從網(wǎng)絡(luò)獲取
static inline BOOL verifiedNSArray(id arraylike) {
    if (arraylike && ![arraylike isEqual:[NSNull null]] && [[arraylike class] isSubclassOfClass:[NSArray class]] && [arraylike count] > 0) {
        return YES;
    } else {
        return NO;
    }
}

// 用法:數(shù)組類型 && 未越界
if (verifiedNSArray(self.dataArray) && indexPath.row < self.dataArray.count) {
        
}
  • 字典
// 判斷是否是字典式矫,一般從網(wǎng)絡(luò)獲取
static inline BOOL verifiedNSDictionary(id dictlike) {
    if (dictlike && ![dictlike isEqual:[NSNull null]] && [[dictlike class] isSubclassOfClass:[NSDictionary class]]) {
        return YES;
    } else {
        return NO;
    }
}

// 用法:數(shù)據(jù)的解析
if (verifiedNSDictionary(responseObject)) {

}

注釋

優(yōu)秀的代碼大部分是可以自描述的,我們完全可以用程代碼本身來表達(dá)它到底在干什么役耕,而不需要注釋的輔助采转。

但并不是說一定不能寫注釋,有以下四種情況比較適合寫注釋:
公共接口(注釋要告訴閱讀代碼的人瞬痘,當(dāng)前類能實(shí)現(xiàn)什么功能)故慈。
涉及到比較深層專業(yè)知識(shí)的代碼(注釋要體現(xiàn)出實(shí)現(xiàn)原理和思想)。
容易產(chǎn)生歧義的代碼(但是嚴(yán)格來說框全,容易讓人產(chǎn)生歧義的代碼是不允許存在的)察绷。
踩過坑的代碼(如特定機(jī)型系統(tǒng)會(huì)崩潰之類的代碼,如有解決方案或鏈接附上最佳)津辩。

  1. Class注釋
/**
 Gif集錦拆撼,中間Gif視圖
 */
@interface DQGifCollectionGifView : UIView

@end
  1. property注釋
@interface DeliveryModel : NSObject

/// 提貨劵所在商圈id
@property (nonatomic, assign) long long mallId;
/// 商圈全稱
@property (nonatomic, copy) NSString *mallFullName;
/// 商圈簡(jiǎn)稱
@property (nonatomic, copy) NSString *mallShortName;
/// 提貨劵號(hào)
@property (nonatomic, copy) NSString *credentialsCode;
/// 總金額
@property (nonatomic, assign) NSInteger totalAmount;
  1. 方法注釋
/**
 *  圈子列表(達(dá)人榜/置頂/貼子列表)
 *
 *  @param urlStr 請(qǐng)求URLStr
 *  @param params 參數(shù)
 *  @param block 返回的結(jié)果和code
 */
- (void)getCircleRefreshHeadListWithUrl:(NSString *)urlStr params:(NSDictionary *)params resultBackBlock:(DQAnalyzeBackBlock)block;

參考文獻(xiàn)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市丹泉,隨后出現(xiàn)的幾起案子情萤,更是在濱河造成了極大的恐慌,老刑警劉巖摹恨,帶你破解...
    沈念sama閱讀 216,591評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件筋岛,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡晒哄,警方通過查閱死者的電腦和手機(jī)睁宰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來寝凌,“玉大人柒傻,你說我怎么就攤上這事〗夏荆” “怎么了红符?”我有些...
    開封第一講書人閱讀 162,823評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)伐债。 經(jīng)常有香客問我预侯,道長(zhǎng),這世上最難降的妖魔是什么峰锁? 我笑而不...
    開封第一講書人閱讀 58,204評(píng)論 1 292
  • 正文 為了忘掉前任萎馅,我火速辦了婚禮,結(jié)果婚禮上虹蒋,老公的妹妹穿的比我還像新娘糜芳。我一直安慰自己飒货,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,228評(píng)論 6 388
  • 文/花漫 我一把揭開白布峭竣。 她就那樣靜靜地躺著塘辅,像睡著了一般。 火紅的嫁衣襯著肌膚如雪邪驮。 梳的紋絲不亂的頭發(fā)上莫辨,一...
    開封第一講書人閱讀 51,190評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音毅访,去河邊找鬼沮榜。 笑死,一個(gè)胖子當(dāng)著我的面吹牛喻粹,可吹牛的內(nèi)容都是我干的蟆融。 我是一名探鬼主播,決...
    沈念sama閱讀 40,078評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼守呜,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼型酥!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起查乒,我...
    開封第一講書人閱讀 38,923評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤弥喉,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后玛迄,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體由境,經(jīng)...
    沈念sama閱讀 45,334評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,550評(píng)論 2 333
  • 正文 我和宋清朗相戀三年蓖议,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了虏杰。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,727評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡勒虾,死狀恐怖纺阔,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情修然,我是刑警寧澤笛钝,帶...
    沈念sama閱讀 35,428評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站愕宋,受9級(jí)特大地震影響婆翔,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜掏婶,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,022評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望潭陪。 院中可真熱鬧雄妥,春花似錦最蕾、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至枝秤,卻和暖如春醋拧,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背淀弹。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工丹壕, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人薇溃。 一個(gè)月前我還...
    沈念sama閱讀 47,734評(píng)論 2 368
  • 正文 我出身青樓菌赖,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親沐序。 傳聞我的和親對(duì)象是個(gè)殘疾皇子琉用,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,619評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • iOS編程規(guī)范0規(guī)范 0.1前言 為??高產(chǎn)品代碼質(zhì)量,指導(dǎo)廣大軟件開發(fā)人員編寫出簡(jiǎn)潔、可維護(hù)策幼、可靠邑时、可 測(cè)試、高效...
    iOS行者閱讀 4,455評(píng)論 21 35
  • 前言 代碼規(guī)范可以說是老生常談的話題了, 也是程序員自我修養(yǎng)的一種體現(xiàn)特姐, 雖然一套好的代碼規(guī)范不能使程序運(yùn)行的更加...
    kakukeme閱讀 1,053評(píng)論 0 51
  • 一晶丘、命名規(guī)范 1、統(tǒng)一要求含義清楚到逊,盡量做到不需要注釋也能了解其作用铣口,若做不到,就加注釋觉壶,使用全稱脑题,不使用縮寫。 ...
    Untils閱讀 564評(píng)論 0 0
  • 提起迪麗熱巴,她塑造的角色中最討喜的應(yīng)該是她在《三生三世十里桃花》中所飾演的鳳九争剿。俏皮可愛的她贊美自己姑姑時(shí)露出狐...
    神馬綜藝閱讀 2,334評(píng)論 0 22
  • 早課:荷花線描 這幅荷花圖原本打算昨天一起臨的已艰,結(jié)果時(shí)間不夠了。實(shí)際今天也是用了一小時(shí)蚕苇。 看起來簡(jiǎn)單哩掺,畫起來還是不...
    紫陌來自洗線廬閱讀 666評(píng)論 2 5