Swift代码规范

团队的Swift代码规范,参考Swift Style GuideSwift 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 编码规范

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,013评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,205评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,370评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,168评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,153评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,954评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,271评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,916评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,382评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,877评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,989评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,624评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,209评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,199评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,418评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,401评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,700评论 2 345

推荐阅读更多精彩内容

  • 注: Copy 自 cocoachina 英文原文:Swift Style Guide 翻译作者:码农网 – 豆照...
    Mid_Chan阅读 697评论 0 0
  • 1. 代码格式 1.1 使用四个空格进行缩进。 1.2 每行最多160个字符,这样可以避免一行过长。 (Xcode...
    余一波_Bobby阅读 5,902评论 1 3
  • 当你试图解决一个别人代码中的问题时,难得不是怎么解决这个问题,而是先得找到、读懂这段代码。 推荐文档:https:...
    小小土豆dev阅读 983评论 0 6
  • 法理学的天空群星闪耀,我们也一再在这篇辉煌的天幕下头晕目眩。然而,在这众多的先贤之中,最使我心潮澎湃、如沐甘霖的,...
    郭绿狮阅读 1,696评论 1 1
  • “你想做一个体面的人,有点熟能生巧的倦怠,你想做一个麻木的人,有种信手拈来的自暴自弃,你想做一个怀揣梦想的人,却步...
    二人余安阅读 339评论 0 2