iOS代碼規范

命名規范

原則: 防止命名沖突、可讀性高
方式: 駝峰式命名法
說明: 每個模塊都需要加上前綴

一、常量命名

1.1 在常量前邊加上字母k作為標記

static const NSTimeInterval kAnimationDuration = 0.3

1.2 定義作為NSDictionary或者NSNotification的key值字符串時加上const關鍵字

NSString *const UIApplicationDidEnterBackgroundNotification

1.3 若常量作用域超出.m文件,需要在類外可見時,使用extern關鍵字,并加上類名前綴

extern NSString *const PGThumbnailSize

1.4 全局常量包括 通知 或者 關鍵字 都盡可能使用const定義
Tips


  • 使用宏定義可能導致宏被 重定義,引用不同的文件可能導致 宏不同
  • #define 也需要添加k前綴

二、枚舉命名
2.1 枚舉類型 命名要加相關類名前綴并且 枚舉值命名 要加枚舉類型前綴,示例如下

typedef NS_ENUM(NSInteger, UIViewAnimationTransition) {
    UIViewAnimationTransitionNone,
    UIViewAnimationTransitionFlipFromLeft,
    UIViewAnimationTransitionFlipFromRight,
    UIViewAnimationTransitionCurlUp,
    UIViewAnimationTransitionCurlDown,
};

typedef NS_OPTIONS(NSUInteger, UIControlState) {
    UIControlStateNormal       = 0,
    UIControlStateHighlighted  = 1 << 0,
    UIControlStateDisabled     = 1 << 1,
};

優點:增強類型檢查,更好的代碼可讀性
三、 變量和對象的命名
方式: 修飾+類型

@property (nonatomic, strong) UILabel *titleLabel; //表示*標題*的label,是*UILabel*類型
@property (nonatomic, strong) UIButton *confirmButton; //表示*確認*的button,是*UIButton*類型

對于BOOL類型,需要加is前綴

- (BOOL)isEqualToString:(NSString *)aString;
- (BOOL)hasPrefix:(NSString *)aString;

四、 方法命名
4.1 添加 參數 提示

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil;
- (void)performSegueWithIdentifier:(NSString *)identifier sender:(id)sender;

4.2 回調方法通知方法 的命名
原則: 動作發生之前用Will,發生之后用Did,詢問是否發生用Should

- (nullable NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath;  //將要選擇這一行cell
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath; //已經選擇這一行cell
- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(6_0); //是否高亮(選擇這一行cell)

4.3 回調方法第一個參數是調用者

- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions;
- (void)buttonTapped:(UIButton*)sender;

4.4 方法符合語法
大部分方法可以分為兩類:要什么做什么


  • 要什么
    表示取得某個對象,要以名詞作為方法的開頭
- (UIImage *)imageNamed:(NSString *)name;

  • 做什么
    表示執行某種操作,要以動詞作為方法開頭
- (void)setUpNavBar

書寫規范

一、 ViewController 書寫規范
1.1 方法書寫順序(依次)

* 生命周期  
* 基類public方法  
* 代理方法  
* 本類private方法  
* 通知方法  
* 請求方法  
二、*代碼目錄分類* 規范  
2.1 總代碼目錄架構  
![](http://upload-images.jianshu.io/upload_images/59913-5dd33a1c3e43b2fc.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

2.2 Managers 目錄  
![](http://upload-images.jianshu.io/upload_images/59913-c0b2dd78ed275195.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)  
2.3 Models 目錄  
![](http://upload-images.jianshu.io/upload_images/59913-e0d7c9a4bbb55550.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)  
2.4 Controllers 目錄  
![](http://upload-images.jianshu.io/upload_images/59913-176279229c98d2ee.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)  
2.5 General 目錄  
![](http://upload-images.jianshu.io/upload_images/59913-4dfbc152ac0b9745.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)  
2.6 Macros 目錄  
![](http://upload-images.jianshu.io/upload_images/59913-feffc82e7f96feb0.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)  
2.7 Vendors 目錄  
![](http://upload-images.jianshu.io/upload_images/59913-e137531eda752764.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)  
2.8 Assets.xcassets 目錄  
![](http://7xpu01.com1.z0.glb.clouddn.com/Assets.xcassets%E7%9B%AE%E5%BD%95.png)  
三、 寫碼規范  
3.1 判斷**nil**或者**YES/NO**  

```javascript
if (obj) 
  { 
    //... 
  }
if (!obj) 
  { 
    //... 
  }

3.2 NSArray NSDictionary 初始化方法

NSArray *contacters = @[@"Allen", @"Bob", @"Chirs"];
NSDictionary *bookInfo = @{@"BookName":@"iOS開發之進階篇", @"BookPrice":@"999999.0RMB", @"BookAuthor":@"RenSihao"};
NSNumber *isHide = @NO;
NSNumber *errorCode = @404;

優點:簡潔明了,同時防止初始化進去一個nil

3.3 定義屬性盡可能寫全參數

@property (nonatomic, readwrite, copy) NSString *name;
  • 如果是內部使用的屬性, 需定義成該類的私有屬性(寫在.m文件的class extension里)
  • 對于擁有Mutable子類型的對象, 例如NSString NSArray NSDictionary NSDictionary, 一定要定義成copy屬性
  • 盡量不要暴露mutable類型的對象在public interface, 建議在.h定義一個Inmutable類型的屬性, 然后在.m的get函數里面返回一個內部定義的mutable變量
  • 不要出現混合聲明,盡可能都使用@property聲明
    3.4 BOOL類型賦值
BOOL isAdult = age > 18;
 

3.5 拒絕死值

if (country = Countries.China) 
  { //... }
const int adultAge = 18;
if (age > adultAge)
  { //... }

3.6 復雜的條件判斷
如果判斷較為復雜,盡可能寫到一個方法里

if ([self canDeleteAccount:account])
    { //... }
/**
 method
*/
- (BOOL)canDeleteAccount:(account)
{
    if (account.balance == 0  || account.owner.isDead == YES || account.isCancel == YES)
    {
        return YES;
    }
    else
    {
        return NO;
    }
}

3.7 嵌套判斷

if (!user.account) return NO;
if (!user.password) return NO;
return YES;

3.8 使用Block避免循環引用

  • block內部使用外部聲明的強引用去訪問對象A,則block內部會產生一個強引用指向對象A
  • block內部使用外部聲明的弱引用去訪問對象A,則block內部會產生一個弱引用指向對象A
__weak typeof(self) weakSelf = self;
obj.block = ^ {
    __strong typeof(self) strongSelf = self;
    if (strongSelf)
    {
        [strongSelf doSomething]; //strongSelf != nil
    }
    else 
    {
        //maybe nothing...
        return ;
    }
}

3.9 宏的格式
宏要寫成大寫至少一個字母大寫,全部小寫有時候Xcode不會自動提示
3.10 加載xib
加載xib名稱使用 NSStringFromClass()

[self.tableView registerNib:[UINib nibWithNibName:NSStringFromClass([UserListCell class]) bundle:nil] forCellReuseIdentifier:ID];

3.11 繼承
子類繼承父類方法,需要重寫一定要先調用父類進行初始化操作
建議在父類方法后追加 NS_REQUIRES_SUPER ,作用是子類重寫這個方法就會自動警告提示要調用這個super方法

- (void)addAllNotifications;

3.12 命名控件避開系統命名
例如

@property (nonatomic, strong) UILabel *textLabel; //錯誤命名
@property (nonatomic, strong) UILabel *contentLabel; //正確命名

3.13 id類型
id類型屬性調用不能用點語法, 調用get方法只能用中括號

[id 方法名]

3.14 判斷if書寫方式

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

3.15 快速調試
需要注釋掉一個方法,在該方法內部第一行return即可,無需大段注釋
3.16 監聽鍵盤通知
使用

UIKIT_EXTERN NSString *const UIKeyboardWillChangeFrameNotification

優點:無論鍵盤切換輸入法,切換表情等原因導致frame更改,該通知一定會監聽得到
3.17 通知命名
使用const修飾,以Notification結尾
3.18 BOOL類型屬性
如果是聲明BOOL類型,建議在括號中重寫get方法

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

3.19 自定義方法
不能使用and這個單詞連接參數

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

3.20 點語法
盡可能使用點語法訪問屬性,但是訪問其他實例對象使用括號

view.backgroundColor = [UIColor redColor];
[UIApplication sharedApplication].delegate; //推薦

[view setBackgroundColor:[UIColor redColor]];
UIApplication.sharedApplication.delegate; //不推薦

3.21 引用頭文件
類的頭文件(.m文件)盡量不要引用其他頭文件,無需知道類的內部細節使用@class即可


最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • iOS編程規范0規范 0.1前言 為??高產品代碼質量,指導廣大軟件開發人員編寫出簡潔、可維護、可靠、可 測試、高效...
    iOS行者閱讀 4,502評論 21 35
  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,948評論 18 139
  • 概要 Objective-C是一門面向對象的動態編程語言,主要用于編寫iOS和Mac應用程序。關于Objectiv...
    DreamMmMmM閱讀 1,197評論 0 7
  • 命名規范 總的來說, iOS命名兩大原則是:可讀性高和防止命名沖突(通過加前綴來保證). Objective-C ...
    FreshCoder閱讀 438評論 0 3
  • WinPcap編程系列文章 WinPcap編程【1】--編程環境的設置(盡管似乎我加了lib也沒有配置成功,某個程...
    ZoeyeoZ閱讀 1,018評論 0 0