Swift代码规范

团队的Swift代码规范,参考Swift Style Guide和Swift 4.0 编码规范,并根据团队实际需要做调整。

一、编码格式

1.1 使用二元运算符(+, -,==, 或->)的前后都需要添加空格

let value = 1 + 2

1.2 在逗号前面不添加空格,后面加一个空格

let titleArray = [1, 2, 3, 4, 5]

1.3 在冒号前面不添加空格,后面添加一个空格。

// 指定类型
let someViewController: SomeViewController

// 字典语法
let ninjaDictionary: [String: AnyObject] = [
    "fightLikeDairyFarmer": false,
    "disgusting": true
]

// 调用函数
someFunction(someArgument: "Kitten")

// 父类
class SomeViewController: UIViewController {
    /* ... */
}

// 协议
extension SomeViewController: UITableViewDataSource {
    /* ... */
}

1.3 左大括号不用另起一行

class SomeClass {
    func someMethod() {
        if x == y {
            /* ... */
        } else if x == z {
            /* ... */
        } else {
            /* ... */
        }
    }
    /* ... */
}

1.4 判断语句中,只有一个判断条件的时候,不用加括号

if typeValue == 1 {
    // code
}

1.5 在访问枚举类型时,使用点语法

enum Direction {
    case north
    case south
    case east
    case west
}
let currentDirection = .west

1.6 遵守Xcode内置的缩进格式(格式快捷键:CTRL-i),当声明的一个函数需要跨多行时,推荐使用Xcode默认格式。

// Xcode针对跨多行函数声明缩进
func myFunctionWithManyParameters(parameterOne: String,
                                  parameterTwo: String,
                                  parameterThree: String) {
    // Xcode会自动缩进
    print("\(parameterOne) \(parameterTwo) \(parameterThree)")
}

// Xcode针对多行 if 语句的缩进
if myFirstVariable > (mySecondVariable + myThirdVariable) && 
    myFourthVariable == .SomeEnumValue {
    // Xcode会自动缩进
    print("Hello, World!")
}

1.7 view controller的方法顺序,根据生命周期排列。且在viewWillAppear、viewDidAppear中,需要先调用super方法。在viewWillDisappear、viewDidDisappear中,需最后调用super方法

    override func viewDidLoad() {
        super.viewDidLoad()
        // your code
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        // your code
    }
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        // your code
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        // your code
        super.viewWillDisappear(animated)
    }
    
    override func viewDidDisappear(_ animated: Bool) {
        // your code
        super.viewDidDisappear(animated)
    }
    
    deinit {
        // your code
    }

    // other function...

二、命名规范

2.1 常量,变量,函数,方法的命名规则使用小驼峰规则,首字母小写,类型名使用大驼峰规则,首字母大写。

class MyClass: class {
    let myImageView: UIImageView
    let myName: String
}

2.2 当命名里出现缩写词时,缩写词要么全部大写,要么全部小写,以首字母大小写为准。(服务器返回model的key除外)

let htmlString = "https://www.baidu.com"
let urlString:  URLString
let userID:  UserID

class HTMLModel {
    //
}

2.3 bool类型命名时,使用is作为前缀(该条非强制,仅供参考)

var isMine: Bool = false

2.4 命名应该具有描述性

// 推荐
class RoundAnimatingButton: UIButton { /* ... */ }

// 不推荐
class CustomButton: UIButton { /* ... */ }

2.5 不要简写命名,或用单个字母命名。(允许使用常见的缩写,如html、url、id等)

// 推荐
class RoundAnimatingButton: UIButton {
    let animationDuration: NSTimeInterval
    func startAnimating() {
        let firstSubview = subviews.first
    }
}

// 不推荐
class RoundAnimating: UIButton {
    let aniDur: NSTimeInterval
    func srtAnmating() {
        let v = subviews.first
    }
}

2.6 如果原有命名不能明显表明类型,则属性命名内要包括类型信息。

// 推荐
class ConnectionTableViewCell: UITableViewCell {
    let personImageView: UIImageView
    let animationDuration: NSTimeInterval
    // 作为属性名的firstName,很明显是字符串类型,所以不用在命名里不用包含String
    let firstName: String
    let popupViewController: UIViewController
    // 如果需要使用UIViewController的子类,如TableViewController, CollectionViewController, SplitViewController, 等,需要在命名里标名类型。
    let popupTableViewController: UITableViewController
    // 当使用outlets时, 确保命名中标注类型。
    @IBOutlet weak var submitButton: UIButton!
    @IBOutlet weak var emailTextField: UITextField!
    @IBOutlet weak var nameLabel: UILabel!
}

// 不推荐
class ConnectionTableViewCell: UITableViewCell {
    // 这个不是 UIImage, 不应该以Image 为结尾命名。
    let personImage: UIImageView
    // 这个不是String,应该命名为 textLabel
    let text: UILabel
    // animation 不能清晰表达出时间间隔
    // 建议使用 animationDuration 或 animationTimeInterval
    let animation: NSTimeInterval
    // transition 不能清晰表达出是String
    // 建议使用 transitionText 或 transitionString
    let transition: String
    // 这个是ViewController,不是View
    let popupView: UIViewController
    // 为了保持一致性,建议把类型放到变量的结尾,而不是开始,如submitButton
    @IBOutlet weak var btnSubmit: UIButton!
    @IBOutlet weak var buttonSubmit: UIButton!
    // 在使用outlets 时,变量名内应包含类型名,或其他能表达类型含义的单词。
    // 这里建议使用 firstNameLabel
    @IBOutlet weak var firstName: UILabel!
}

2.7 数组的名称,推荐使用元素的复数命名。

// 推荐
var entities: [SPEntity] = []

// 不推荐
var entityList: [SPEntity] = []

三、语法规范

3.1 可选类型拆包取值时,使用if let 判断

if let data = result.data {
    // code
}

3.2 多个可选类型拆包取值时,将多个if let 判断合并

if let name = person.name, let age = person.age {
    // code
}

3.3 尽量不要使用 as! 或 try!(除非可以确定不会出现异常)

// 使用if let as?
if let name = person.name as? String {
    // code
}

3.4 当对外接口不兼容时,使用@available(iOS x.0, *) 标明接口适配的起始系统版本号

@available(iOS 8.0, *)
func myFunction() {
    // code
}

3.5 尽可能的多使用let,少使用var。

3.6 当拆包取值时,使用和被拆包取值变量相同的名称。

guard let myVariable = myVariable else {
    return
}

3.7 在创建类常量的时候,使用 static 关键词修饰。

class MyTableViewCell: UITableViewCell {
    static let reuseIdentifier = String(MyTableViewCell)
    static let cellHeight: CGFloat = 80.0
}

3.8 推荐使用提前返回的策略,而不是 if 语句的嵌套。使用 guard 语句可以改善代码的可读性。

// 推荐
func eatDoughnut(atIndex index: Int) {
    guard index >= 0 && index < doughnuts else {
        // 如果 index 超出允许范围,提前返回。
        return
    }
    let doughnut = doughnuts[index]
    eat(doughnut)
}

// 不推荐
func eatDoughnuts(atIndex index: Int) {
    if index >= 0 && index < donuts.count {
        let doughnut = doughnuts[index]
        eat(doughnut)
    }
}

3.9 当需要判断变量是否是nil,但又不需要访问变量值的时候,推荐直接把它跟nil做比较。

// 推荐
if someOptional != nil {
    // do something
}

// 不推荐
if let _ = someOptional {
    // do something
}

四、注释

对于写代码,注释就是解释。除非在非常必要的时候进行适当的注释,否则只会增加阅读代码“噪声”。
尽量用注释说明why(为什么这里代码要这么写),而不是what(这里代码写的是什么)

参考文档
Swift Style Guide
Swift 4.0 编码规范

你可能感兴趣的:(Swift代码规范)