1. 程式人生 > >iOS開發手冊(精華篇)

iOS開發手冊(精華篇)

1.專案基礎

1.1 專案新建資訊

  • Product Name:工程名。
  • Team:開發者賬號資訊,沒有選擇None,個人開發者賬號(含Personal Team),公司/企業賬號(如:XXX Co.,LTD),也可以暫時選擇None,後續再配置除錯。
  • Organization Name:個人開發者賬號(自定義名字),公司/企業賬號(如:XXX Co.,LTD),此處內容明顯體現在程式碼檔案頭部註釋中。
  • Organization Identifier:個人開發者賬號(自定義標識),公司/企業賬號(域名反寫如:com.xxx)。
  • Bundle Identifier:自動生成格式為 [Organization Identifier] + [Product Name],也可後續配置時進行修改。
  • Language:根據需要選擇Objective-C 或者 Swift。
  • Use Core Data:根據專案情況勾選,如果明確需要請直接勾選,也可後續新增。
  • Include Unit Tests:單元測試,根據需要勾選,也可後續新增。
  • Include UI Tests:UI測試,根據需要勾選,也可後續新增。
  • Source Control:預設git進行版本管理,根據需要勾選,也可後續新增。

1.2 專案初始配置

  • Display Name:應用名稱。
  • Deployment Info:系統版本、裝置、螢幕方向、狀態列等,
  • Build Active Architecture Only:一般Debug模式YES,Release模式NO。如果Release模式為YES,那麼上傳AppStore之後會顯示大量而具體的相容裝置,Release模式為NO則僅顯示模糊的相容資訊。
  • Architecture:預設$(ARCHS_STANDARD)不作修改。
  • Valid Architecture:預設arm64/armv7/armv7s不作修改。模擬器32位處理器是i386架構,模擬器64位處理器是x86_64架構,真機32位處理器是armv7或armv7s架構,真機64位處理器是arm64架構。

1.3 專案檔案結構

  • 所有的檔案應放在工程中的專案目錄下。
  • 專案檔案和物理檔案需保持一致。
  • Xcode建立的任何組(group)都必須有資料夾對映。
  • 專案檔案不僅可以按照業務型別分組,也可以根據功能分組。

2.程式碼格式規範

這是小編的iOS開發交流群:624212887,裡面都是iOS開發,全棧發展,歡迎入駐!——點選:加入

2.1 程式碼註釋格式

  • 檔案註釋:採用Xcode自動生成的註釋格式。

    //
    //  AppDelegate.h
    //  專案名稱
    //
    //  Created by 開發者姓名 on 2018/6/8.
    //  Copyright © 2018年 公司名稱. All rights reserved.
    //
    
  • import註釋:如果有一個以上的import語句,對這些語句進行分組,每個分組的註釋是可選的

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

    /**
    <#Description#>
    
    @param application <#application description#>
    @param launchOptions <#launchOptions description#>
    @return <#return value description#>
    */
    - (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 程式碼命名基礎

  • 最好是既清晰又簡短,但不要為簡短喪失清晰性,並使用駝峰命名法。

  • 名稱通常不縮寫,即使名稱很長也要拼寫完全(禁止拼音),然而可使用少數非常常見的縮寫,部分舉例如下:

    常用縮寫詞 含義 常用縮寫詞 含義
    app application max maximum
    alt alternate min minimum
    calc calculate msg message
    alloc allocte rect rectangle
    dealloc deallocte msg message
    init initialize temp temporary
    int integer func function
  • 由於Cocoa(Objective-C)沒有C++一樣的名稱空間機制,需新增字首(公司名首字母)防止命名衝突,字首使用2個字元(以下統稱專案字首)。

  • 常見的單詞略寫:ASCII,PDF,HTTP,XML,URL,JPG,GIF,PNG,RGB

3.2 類和協議命名

  • 類名應明確該類的功能,並且要有專案字首防止命名衝突。
  • 協議組合一組相關的方法,不關聯具體的一個類,使得某些相似類有統一的介面,這種協議的命名應採用動名詞形式(ing),例如:NSLocking。
  • 協議組合一些不相關的方法(主要是避免建立多個獨立的協議),僅僅關聯某一個具體的類(該類是協議的具體體現者),這種協議用該類名命名,例如:NSObject。
  • 委託形式的協議命名為類名加上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:(nullableCGFloat *)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_mine_setting_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引入,並且指定版本號。
  • 原始檔方式需引入檔案到工程目錄下。
  • 原始檔方式需注意有無版本說明資訊(可能在README檔案中,也可能在某個.h標頭檔案中,又或者有Version檔案)沒有時需在庫檔案目錄下新增版本說明檔案,

7.程式碼版本管理

  • 版本管理工具:svn 或 git。

  • svn檔案管理配置:目錄~/.subversion開啟config檔案全域性配置global-ignore,所有的倉庫都會受到影響,而svn:ignore隻影響倉庫目錄。

  • git檔案管理配置:.gitignore_global為全域性配置,而倉庫目錄下的.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介面化構建注、xcodebuild終端命令構建。
  • 自動化構建:Jenkins+Fastlane、xcodebuild指令碼執行 。
  • 內測分發渠道:fir.im蒲公英等。
  • 線上分發渠道:AppStore。

總結

希望本文的內容對大傢俱有一定的參考學習價值,同時歡迎大家進入小編iOS開發交流群:624212887,互相探討技術!——點選:加入