iOS開發手冊

1.工程文件結構

  • 所有的文件應放在工程中的項目目錄下。
  • 項目文件和物理文件需保持一致。
  • Xcode創建的任何組(group)都必須在文件系統中有映射。
  • 項目文件不僅可以按照業務類型分組,也可以根據功能分組。

2.代碼格式規範

2.1 代碼註釋格式

  • 文件註釋:採用Xcode自動生成的註釋格式。
//
// AppDelegate.h
// 項目名稱
//
// Created by 開發者姓名 on 2018/6/8.
// Copyright © 2018年 公司名稱. All rights reserved.
//
  • import註釋:如果有一個以上的import語句,對這些語句進行分組,每個分組的註釋是可選的
// Framework
#import
// Model
#import "WTUser.h"

// View
#import "WTView.h"
  • 方法註釋:Xcode8之後快捷鍵自動生成(option + command + /)。
/**

@param application
@param launchOptions
@return
*/
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;
  • 代碼塊註釋:單行的用 “// + 空格” 開頭, 多行用“/ /”。
  • 2.2 代碼結構與排版
  • 聲明文件:方法順序和實現文件的順序保持一致,根據需要用”#pragma mark -“將方法分組。
  • 實現文件:必須用”#pragma mark -“將方法分組。分組前後優先級:Lifecycle方法 > Public方法 > UI方法 > Data方法 > Event方法 > Private方法(邏輯處理等) > Delegate方法 > 部分Override方法 > Setter方法 > Getter方法。
#pragma mark - Lifecycle
- (instancetype)init {}
- (void)viewDidLoad {}
- (void)viewWillAppear:(BOOL)animated {}
- (void)viewDidAppear:(BOOL)animated {}
- (void)viewWillDisappear:(BOOL)animated {}
- (void)viewDidDisappear:(BOOL)animated {}

- (void)didReceiveMemoryWarning {}
- (void)dealloc {}
#pragma mark - Public
- (void)refreshData {}
#pragma mark - UI
- (void)initSubViews {}
#pragma mark - Data
- (void)initData {}
- (void)constructData {}
#pragma mark - Event
- (void)clickButton:(UIButton *)button {}
#pragma mark - Private
- (CGFloat)calculateHeight {}
#pragma mark - UIScrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {}
#pragma mark - Override
- (BOOL)needNavigationBar {}
#pragma mark - Setter
- (void)setWindow:(UIWindow *)window {}
#pragma mark - Getter
- (UIWindow *)window {}
  • 變量:優先使用屬性聲明而非變量聲明,注意屬性修飾符、變量類型、變量之間的間隔。
@property (strong, nonatomic) UIWindow *window;
  • 點語法:應始終使用點語法來訪問和修改屬性。
  • 間距要求如下:
  • 一個縮進使用四個空格。
  • 在”-“或者”+“號之後應該有一個空格,方法的大括號和其它大括號始終和聲明在同一行開始,在新的一行結束,另外方法之間應該空一行。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if (door.isClosed) {
// Do something
} else {
// Do something
}
return YES;
}
  • 長度要求如下:
  • 每行代碼的長度不應該超過100個字符。
  • 單個函數或方法的實現代碼控制在50行以內。
  • 單個文件裡的代碼行數控制在500~600行之內。

3.代碼命名規範

3.1 代碼命名基礎

  • 最好是既清晰又簡短,但不要為簡短喪失清晰性,並使用駝峰命名法。
  • 名稱通常不縮寫,即使名稱很長也要拼寫完全(禁止拼音),然而可使用少數非常常見的縮寫,部分舉例如下:
  • 常用縮寫詞含義常用縮寫詞含義appapplicationmaxmaximumaltalternateminminimumcalccalculatemsgmessageallocallocterectrectangledeallocdealloctemsgmessageinitinitializetemptemporaryintintegerfuncfunction
  • 由於Cocoa(Objective-C)沒有C++一樣的命名空間機制,需添加前綴(公司名首字母)防止命名衝突,前綴使用2個字符(以下統稱項目前綴)。
  • 常見的單詞略寫:ASCII,PDF,HTTP,XML,URL,JPG,GIF,PNG,RGB

3.2 類和協議命名

  • 類名應明確該類的功能,並且要有項目前綴防止命名衝突。
  • 協議組合一組方法作為一個類的部分接口使用, 用類名作為協議名,例如:NSObject。
  • 協議僅僅組合一組方法而不關聯具體類,這種協議的命名應採用動名詞形式(ing)。
  • 委託形式的協議命名為類名加上Delegate,例如:UIScrollViewDelegate。

3.3 變量和屬性命名

  • 變量名應前置下劃線“_”,屬性名沒有下劃線。
  • 屬性本質上是存取方法setter/getter,可進行重寫(注意內存管理)。
@property (strong, nonatomic) UIWindow *window;
- (void)setWindow:(UIWindow *)window;
- (UIWindow *)window;
  • 可以適當的對setter/getter進行別名設置。
@property(nonatomic,getter=isUserInteractionEnabled) BOOL userInteractionEnabled;

3.4 方法和函數命名

  • 方法名和函數名一般不需要前綴,但函數(C語言形式)作為全局作用域的時候最好加上項目前綴。
  • 表示行為的方法名稱以動詞開頭,但不要使用do/does等無實際意義的助動詞。
  • 參數前面的單詞要能夠描述該參數,並且參數名最好能用描述該參數的單詞命名。
- (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2;
  • 方法中多個參數可以使用適當的介詞進行連接。
// 後續多個參數使用with
- (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2;
// 添加適當介詞能夠使方法的含義更明確

- (BOOL)lockWhenCondition:(NSInteger)condition beforeDate:(NSDate *)limit;
// 第一個參數用了with,後面的參數不使用with
- (instancetype)initWithImage:(nullable UIImage *)image highlightedImage:(nullable UIImage *)highlightedImage;
  • 只有在方法返回多個值的時候使用get單詞進行明確。
- (void)getLineDash:(nullable CGFloat *)pattern count:(nullable NSInteger *)count phase:(nullable CGFloat *)phase;
  • 方法返回某個對象實例。
// 類方法創建對象
+ (instancetype)buttonWithType:(UIButtonType)buttonType;
// 單例命名
+ (UIApplication *)sharedApplication;
  • 委託或代理方法命名第一個參數最好能相關某個對象。
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath;
  • 私有方法不要以下劃線“_“開頭,因為系統私有方法保留此方式。
  • 自定義方法和系統方法重名,建議在方法開頭加前綴”xx_methodName“。
  • 3.5 常量和宏的命名
  • const常量外部聲明:在Objective-C文件中優先採用FOUNDATION_EXTERN和UIKIT_EXTERN,而非C語言中的extern。
  • const常量採用駝峰命名原則。
  • const常量根據作用域適當加上前綴(含項目前綴):可供外部使用需加上相應的類名或者模塊前綴,僅文件內部使用需要加上小寫字母“k”.
  • 宏定義每個字母採用大寫,單詞之間用下劃線“_”間隔。
  • 宏定義也可根據作用範圍加上適當前綴,避免命名衝突。
  • 3.6 枚舉的命名
  • 使用枚舉來定義一組相關的整數常量,增強代碼的可讀性。
  • 枚舉可根據作用域添加前綴(含項目前綴),格式:[相關類名或功能模塊名] + [描述] + [狀態]。
  • 建議優先採用Objective-C的聲明NS_ENUM和NS_OPTIONS,少採用C語言形式的enum等枚舉聲明.
  • 枚舉定義時需指定None狀態,並且其rawValue一般為起始值0。
// NS_ENUM
typedef NS_ENUM(NSInteger, UIStatusBarAnimation) {

UIStatusBarAnimationNone = 0,
UIStatusBarAnimationFade = 1,
UIStatusBarAnimationSlide = 2,
}
typedef NS_OPTIONS(NSUInteger, UIRemoteNotificationType) {
UIRemoteNotificationTypeNone = 0,
UIRemoteNotificationTypeBadge = 1 << 0,
UIRemoteNotificationTypeSound = 1 << 1,
UIRemoteNotificationTypeAlert = 1 << 2,
UIRemoteNotificationTypeNewsstandContentAvailability = 1 << 3,
}

3.7 通知命名

  • 外部聲明:在Objective-C文件中優先採用FOUNDATION_EXTERN和UIKIT_EXTERN,而非C語言中的extern。
  • 通知的命名一般都是跨文件使用的,需添加項目前綴。
// [相關聯類名或者功能模塊名] + [will/Did](可選) + [描述] + Notification
UIApplicationDidEnterBackgroundNotification
UIApplicationWillEnterForegroundNotification

3.8 類型別名命名

  • 根據作用域添加前綴(含項目前綴),格式:[類名或功能模塊名] + [描述]。

4.文件資源命名規範

  • 資源文件命名也需加上項目前綴。
  • 資源文件名全小寫,單詞之間用下劃線“_”間隔。
  • 資源文件命名格式:[項目前綴] + [業務] + [文件名]
  • 圖片文件命名格式:[項目前綴] + [業務] + [類型] + [狀態]。
// 常見類型:logol,icon,img
// 常見狀態:normal,selected,highlight
UIImage *image = [UIImage imageNamed:@"wt_setting_icon_normal"];

5.代碼警告處理

  • 注意警告問題的隱蔽性,因此最好修復警告。
  • 警告類型的查看步驟:選中警告 -> 右鍵Reveal in Log(不編譯Reveal in Log是灰色的,因此先編譯) ->查看方括號的內容
  • 如果需要忽略警告,建議優先代碼push或者pop處理。
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-retain-cycles"
// 造成警告的代碼
#pragma clang diagnostic pop
  • 如果警告數量過大,檢查警告類型以及必要性,可xcode配置忽略此類型警告。步驟:選中工程 -> TARGETS -> Build Settings -> Other Warning Flags。
忽略單個和全局配置稍有差別,如下舉例: 

push/pop Other Warning Flags
-Wformat —-> -Wno-format
-Wunused-variable —-> -Wno-unused-variable
-Wundeclared-selector —-> -Wno-undeclared-selector
-Wint-conversion —-> -Wno-int-conversion
  • 也可以在pch等大範圍作用域的頭文件中添加代碼來忽略後續警告:#pragma clang diagnostic ignored “警告名稱” 。

6.外部庫文件引入

  • 庫文件引入最好把警告處理掉。
  • 庫文件引入優先採用CocoaPods引入,並且指定版本號。
  • 源文件方式需引入文件到工程目錄下。
iOS開發手冊


  • 源文件方式需注意有無版本說明信息(可能在README文件中,也可能在某個.h頭文件中,又或者有Version文件)沒有時需在庫文件目錄下新增版本說明文件,

7.代碼版本管理

  • 版本管理工具:svn 或 git。
  • svn文件管理配置:目錄~/.subversion打開config文件配置global-ignore。
  • git文件管理配置:.gitignore文件記錄了被git忽略的文件,作用於本倉庫,常見語法如下:
  • 井號(#)用來添加註釋用的,比如 "#註釋"。
  • build/ : 星號()是通配符,build/*則是要說明要忽略 build 文件夾下的所有內容。
  • *.pbxuser : 表示要忽略後綴名為.pbxuser的文件。
  • !default.pbxuser : 感嘆號(!)是取反的意思,*.pbxuser 表示忽略所有後綴名為.pbxuser的文件,如果加上!default.pbxuser則表示,除了default.pbxuse忽略其它後綴名為pbxuse的文件。
  • 提交信息規範:
  • BUG類型為“Fix + [BUG編號] + [BUG描述]”。
  • 任務類型為“Done + [任務編號] + [任務描述]”。
  • 任務中間態為“Doing + [任務編號] + [任務描述]”。
  • 引入類庫為“import + [類庫名]”。

8.構建和分發

  • 手動構建:Xcode構建注意證書配置。
  • 自動化構建:Jenkins+Fastlane、xcodebuild
  • 內側分發渠道:fir.im、蒲公英等。
  • 線上渠道:AppStore。

閱讀原文:https://segmentfault.com/a/1190000016764626


分享到:


相關文章: