iOS 代碼規(guī)范小建議:

1.精簡代碼, 返回最后一句的值,這個方法有一個優(yōu)點拭卿,所有的變量都在代碼塊中墨礁,也就是只在代碼塊的區(qū)域中有效,這意味著可以減少對其他作用域的命名污染榛臼。但缺點是可讀性比較差

NSURL *url = ({ NSString *urlString = [NSString stringWithFormat:@"%@/%@", baseURLString, endpoint];
[NSURL URLWithString:urlString];
});

2.關(guān)于編譯器:關(guān)閉警告:

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
[myObj performSelector:mySelector withObject:name];
#pragma clang diagnostic pop

3.忽略沒用的變量

#pragma unused (foo)
明確定義錯誤和警告
#error Whoa, buddy, you need to check for zero here!
#warning Dude, don't compare floating point numbers like this!

4.避免循環(huán)引用

如果【block內(nèi)部】使用【外部聲明的強引用】訪問【對象A】, 那么【block內(nèi)部】會自動產(chǎn)生一個【強引用】指向【對象A】
如果【block內(nèi)部】使用【外部聲明的弱引用】訪問【對象A】, 那么【block內(nèi)部】會自動產(chǎn)生一個【弱引用】指向【對象A】
__weak typeof(self) weakSelf = self;
dispatch_block_t block = ^{
   [weakSelf doSomething]; // weakSelf != nil
// preemption, weakSelf turned nil
[weakSelf doSomethingElse]; // weakSelf == nil
};

最好這樣調(diào)用:

__weak typeof(self) weakSelf = self;
myObj.myBlock = ^{
__strong typeof(self) strongSelf = weakSelf;
if (strongSelf) {
     [strongSelf doSomething]; // strongSelf != nil
// preemption, strongSelf still not nil(搶占的時候伊佃,strongSelf 還是非 nil 的)
[strongSelf doSomethingElse]; // strongSelf != nil }
else { // Probably nothing... return;
}
};

5.宏要寫成大寫,至少要有大寫,全部小寫有時候書寫不提示參數(shù);

6.建議書寫枚舉模仿蘋果——在列出枚舉內(nèi)容的同時綁定了枚舉數(shù)據(jù)類型NSUInteger,這樣帶來的好處是增強的類型檢查和更好的代碼可讀性,示例:

// 不推薦寫法
typedef enum{
    UIControlStateNormal       = 0,
    UIControlStateHighlighted  = 1 << 0,
    UIControlStateDisabled     = 1 << 1,
} UIControlState;
// 推薦寫法
typedef NS_OPTIONS(NSUInteger, UIControlState) {
    UIControlStateNormal       = 0,
    UIControlStateHighlighted  = 1 << 0,
    UIControlStateDisabled     = 1 << 1,
};

7.建議加載xib,xib名稱用NSStringFromClass(),避免書寫錯誤

// 推薦寫法
 [self.tableView registerNib:[UINib nibWithNibName:NSStringFromClass([DXRecommendTagVCell class]) bundle:nil] forCellReuseIdentifier:ID];
// 不推薦寫法
 [self.tableView registerNib:[UINib nibWithNibName:@"DXRecommendTagVCell" bundle:nil] forCellReuseIdentifier:ID];

8.場景需求:在繼承中,凡是要求子類重寫父類的方法必須先調(diào)用父類的這個方法進行初始化操作;建議:父類的方法名后面加上NS_REQUIRES_SUPER; 子類重寫這個方法就會自動警告提示要調(diào)用這個super方法,示例代碼

// 注意:父類中的方法加`NS_REQUIRES_SUPER`,子類重寫才有警告提示
- (void)prepare NS_REQUIRES_SUPER;

9.建議書寫屬性名不要和系統(tǒng)一樣,避免發(fā)生莫名其妙的問題;特別注意的是label;屬性名不要寫成textLabel

10.項目中添加plist類型文件,不要命名為info.plist,以防止和系統(tǒng)自帶的文件重名,發(fā)生莫名其妙的問題;

11.如果控制器已經(jīng)加載過,就不用再次加載,優(yōu)化性能

    if (vc.isViewLoaded) return;

12.id類型屬性不能用點語法,調(diào)用get方法只能用中括號調(diào)用,[id 方法名],利用iOS9新特性泛型就可以; 比如數(shù)組;

@property (nonatomic,strong) NSMutableArray<DXTopics *> *topicsM;

13.如果不是屬性,盡量不要點語法,一個老程序員的建議;

14.使用第三方框架,盡量不要更改內(nèi)部文件,而應(yīng)該再次封裝,個性定制;

15.判斷if書寫方式
建議這樣寫

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.row == 0) return 44;
    if (indexPath.row == 1) return 80;
    if (indexPath.row == 2) return 50;
    return 44;
}

而不是

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.row == 0) {
        return 44;
    }else if (indexPath.row == 1){
        return 80;
    }else if (indexPath.row == 2){
        return 50;
    }else{
        return 44;
    }
}

16接手一個新項目,快速的調(diào)試,查看某個模塊或者方法的作用,需要注釋掉一個方法,或者某個代碼塊,直接寫return;而不是全選,注釋掉;
比如:查看這個方法loadNewRecommendTags作用

- (void)loadNewRecommendTags
{
    return;

    [SVProgressHUD show];
    // 取消之前的任務(wù)
    [self.manager.tasks makeObjectsPerformSelector:@selector(cancel)];
    NSMutableDictionary *params = [NSMutableDictionary dictionary];

    params[@"a"] = @"tag_recommend";
    params[@"c"] = @"topic";
    params[@"action"] = @"sub";
    [self.manager GET:DXCommonUrlPath parameters:params success:^(NSURLSessionDataTask * _Nonnull task, id  _Nonnull responseObject) {

        self.recommendTag = [DXRecommendTag mj_objectArrayWithKeyValuesArray:responseObject];
        [self.tableView reloadData];
        [SVProgressHUD dismiss];
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        DXLog(@"%@",error);
        [SVProgressHUD dismiss];
    }];
}

17.在一個自定義的View中,或者自定義cell中,modal出一個控制器建議:

[UIApplication sharedApplication].keyWindow.rootViewController

代替

self.window.rootViewController,因為程序可能不止一個window,self.window可能不是主窗口;

18.建議:
用CGSizeZero 代替 CGSizeMake(0,0);
CGRectZero代替CGRectMake(0, 0, 0, 0);
CGPointZero代替CGPointMake(0, 0)

19.監(jiān)聽鍵盤的通知建議:

UIKIT_EXTERN NSString *const UIKeyboardWillChangeFrameNotification

而不是,下面代碼;因為鍵盤可能因為改變輸入法,切換成表情輸入,切換成英文,那么frame可能會變高,變矮,不一定會發(fā)出下面這些通知,但是肯定會發(fā)上面的通知

UIKIT_EXTERN NSString *const UIKeyboardWillShowNotification;
UIKIT_EXTERN NSString *const UIKeyboardDidShowNotification;
UIKIT_EXTERN NSString *const UIKeyboardWillHideNotification;
UIKIT_EXTERN NSString *const UIKeyboardDidHideNotification;

20.發(fā)布通知的字符串常量規(guī)范,建議模仿蘋果;如上鍵盤的通知的書寫,加上const 保證字符串不可更改,以Notification結(jié)尾,一看就知道是通知;應(yīng)盡量保證可讀性,不要怕句子太長;

NSString *const buttonDidClickNotification = @"buttonDidClickNotification";

21.如果除數(shù)為0,iOS8以下會直接報錯,(NaN—>Not a Number)iOS9不會,所以應(yīng)該判斷,比如服務(wù)器返回圖片的寬高,按比例縮放,CGFloat contentH = textW * self.height / self.width;

22.如果聲明的屬性,只想使用的get方法,不使用set方法,并且不想讓外界更改這個屬性的值,那么建議在括號里面加readonly;示例:

@property(nonatomic,readonly,getter=isKeyWindow) BOOL keyWindow;

23.如果屬性是BOOL類型,建議在括號中重寫get方法名稱,以提高可讀性,示例代碼如上;

24.從系統(tǒng)相冊中取照片之前,應(yīng)該判斷系統(tǒng)相冊是否可用,如果從相機中拍照獲取,要判斷相機是否可用

// 判斷相冊是否可以打開
if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) return;
//  判斷相機是否可以打開
if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) return;

25.在導(dǎo)航控制中,或它的子控制器,設(shè)置導(dǎo)航欄的標(biāo)題應(yīng)該用

self.navigationItem.title = @“標(biāo)題”

而不建議

self.title = @“標(biāo)題”;

26.給cell設(shè)置分割線,建議用setFrame:通過設(shè)置它高度,設(shè)置分割線,而不推薦用給cell底部添加一個高度的UIView,這樣做增加了一個控件,從性能上來講,不如用setFrame設(shè)置高度

27.大量操作圖層會可能造成應(yīng)用很卡,給用戶體驗差,所以盡量不要操作圖層;比如設(shè)置按鈕圓角,比如給button設(shè)置圓角;

self.loginBtn.layer.cornerRadius = 5;
self.loginBtn.layer.masksToBounds = YES;

28.給分類擴充方法,建議加上前綴,比如第三方框架SDWebImage,這樣做跟系統(tǒng)的方法很容易區(qū)分開,減少了程序員之間的溝通成本,同理跟分類添加屬性(利用運行時),建議加前綴,以防止蘋果官方過一段時間添加了一模一樣的屬性名,比如給UITextField分類添加了placeholderColor這個屬性,萬一某天官方給placeholder擴充了這個命名一模一樣的屬性,那么就不好了

29.凡是在storyboard或者xib中給某個控件添加顏色,顏色對角線有分割線,表示可以設(shè)置透明度,如果給這個控件設(shè)置透明度建議在這里設(shè)置,而不是設(shè)置alpha,因為設(shè)置了alpha,那么上面有文字也會隨著透明度變大,而變得不清楚;可以設(shè)置background -->other -->opacity

30.整形轉(zhuǎn)化成浮點型,不建議這么寫 a / b 1.0,這樣寫是錯誤寫法,示例1.5 / 2 1.0;根據(jù)運算法則,從作到右,0 1.0 == 0,而應(yīng)該在前面寫1.0 1.5 /2;建議直接強轉(zhuǎn);(double)a/b;

31.抽取方法,或者寫工具類,能寫類方法,盡量寫成類方法,減少了創(chuàng)建對象的步驟,比如給UIView擴充分類加載xib,viewWithXib;

32.耗時操作應(yīng)該放在子線程,避免卡主主線程,比如計算文件大小,下載大文件,清除緩存;

33.聲明一個屬性,如果是對象,比如數(shù)組,不能以new單詞開始,否則直接報錯,因為new在OC中是生成一個對象的方法,有特殊含義;比如,

@property (nonatomic,strong) NSMutableArray<DXTopics *> *newTopicsM;

注意:如果newtopicsM是一個單詞(區(qū)別于駝峰標(biāo)志),這樣寫不會報錯;如果是基本數(shù)據(jù)類型則不會報錯,比如

@property (nonatomic,assign) int newNumber;

但是如果一定要寫new單詞開頭的屬性,那么聲明屬性的時候,重寫getter方法名稱只不過使用getter方法的時候注意下

34.在自定義方法中,and這個詞的用法應(yīng)該保留沛善。它不應(yīng)該用于多個參數(shù)來說明航揉,就像initWithWidth:height以下這個例子:

- (instancetype)initWithWidth:(CGFloat)width height:(CGFloat)height;

而不應(yīng)該

- (instancetype)initWithWidth:(CGFloat)width andHeight:(CGFloat)height;

35.建議POST請求參數(shù)字典的寫法,這樣比較裝逼~

// NSDictionaryOfVariableBindings這個宏生成一個字典,這個宏可以生成一個變量名到變量值映射的Dictionary,比如:
NSNumber * packId=@(2);
NSNumber *userId=@(22);
NSNumber *proxyType=@(2);
NSDictionary *param=NSDictionaryOfVariableBindings(packId,userId,proxyType);
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市金刁,隨后出現(xiàn)的幾起案子帅涂,更是在濱河造成了極大的恐慌,老刑警劉巖尤蛮,帶你破解...
    沈念sama閱讀 218,386評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件媳友,死亡現(xiàn)場離奇詭異,居然都是意外死亡产捞,警方通過查閱死者的電腦和手機醇锚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來坯临,“玉大人焊唬,你說我怎么就攤上這事】纯浚” “怎么了求晶?”我有些...
    開封第一講書人閱讀 164,704評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長衷笋。 經(jīng)常有香客問我芳杏,道長矩屁,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,702評論 1 294
  • 正文 為了忘掉前任爵赵,我火速辦了婚禮吝秕,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘空幻。我一直安慰自己烁峭,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,716評論 6 392
  • 文/花漫 我一把揭開白布秕铛。 她就那樣靜靜地躺著约郁,像睡著了一般。 火紅的嫁衣襯著肌膚如雪但两。 梳的紋絲不亂的頭發(fā)上鬓梅,一...
    開封第一講書人閱讀 51,573評論 1 305
  • 那天,我揣著相機與錄音谨湘,去河邊找鬼绽快。 笑死,一個胖子當(dāng)著我的面吹牛紧阔,可吹牛的內(nèi)容都是我干的坊罢。 我是一名探鬼主播,決...
    沈念sama閱讀 40,314評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼擅耽,長吁一口氣:“原來是場噩夢啊……” “哼活孩!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起乖仇,我...
    開封第一講書人閱讀 39,230評論 0 276
  • 序言:老撾萬榮一對情侶失蹤憾儒,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后这敬,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體航夺,經(jīng)...
    沈念sama閱讀 45,680評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡蕉朵,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,873評論 3 336
  • 正文 我和宋清朗相戀三年崔涂,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片始衅。...
    茶點故事閱讀 39,991評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡冷蚂,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出汛闸,到底是詐尸還是另有隱情蝙茶,我是刑警寧澤,帶...
    沈念sama閱讀 35,706評論 5 346
  • 正文 年R本政府宣布诸老,位于F島的核電站隆夯,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蹄衷,卻給世界環(huán)境...
    茶點故事閱讀 41,329評論 3 330
  • 文/蒙蒙 一忧额、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧愧口,春花似錦睦番、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至厚骗,卻和暖如春示启,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背溯捆。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評論 1 270
  • 我被黑心中介騙來泰國打工丑搔, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人提揍。 一個月前我還...
    沈念sama閱讀 48,158評論 3 370
  • 正文 我出身青樓啤月,卻偏偏與公主長得像,于是被迫代替她去往敵國和親劳跃。 傳聞我的和親對象是個殘疾皇子谎仲,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,941評論 2 355

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)刨仑,斷路器郑诺,智...
    卡卡羅2017閱讀 134,657評論 18 139
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,139評論 25 707
  • 字符串中第一個只出現(xiàn)一次的字符索引 java javascript
    Ching_Lee閱讀 284評論 0 0
  • 黑天鵝——罕見的,極端影響的杉武,事后才可預(yù)測的事情辙诞。 當(dāng)一個事件成為歷史(過去),我們常自以為知道轻抱。但實際是...
    倩倩愛錢閱讀 437評論 0 0
  • 我會在哪一個月份死去 就會在哪一個月份復(fù)活 我要在那個月份 和所有相識的人一一道別 可是除了你飞涂,除了你 我若愿意與...
    王謫閱讀 267評論 0 5