Swift编码规范

待更新

文件

  • 首字母请用大写
  • 使用MyClass+Additions的格式添加Extension功能

Additions可以自由定义

  • swift文件不要添加PG前缀。

swift会根据模块名作为命名空间。转换后类名为pgOrderModule.ViewController

命名

enum MyEnum {}
struct MyStruct {}

class MyClass {
    var myNum: Int = 1
    func myMethod() {}
}
typealias MyClass2 = MyClass
  • 类型使用大写开头
  • propertymethod使用小写开头,驼峰格式

基础组件,为了防止重名,建议用自己的模块作为前缀

Property

private let num: Int
private(set) var num: Int
@objc private var num: Int

:与类型之间添加空格

使用lazy初始化可以延时加载的属性

class MyClass {
    var lazy num = [1,2,3]
    var lazy num2 = self.test()
}

lazy属性会在第一次使用的时候初始化
一些场景:

  • 有些属性初始化比较耗时,延时初始化
  • 有些属性必须init以后计算

控制流

不要使用()

推荐

if true {
    // do
} else {
    // do
}

不推荐

if (true) {
    // do
} else {
    // do
}
  • 注意空格
  • {/}不换行

使用Guard进行提前返回

推荐
guard !a else {
    return
}
guard !b else {
    return
}
// do
不推荐
if a {
    if b {
        // do
    }
}

优先使用三元运算符?:

推荐
let b = true
let a = b ? 1 : 2

let c: Int?
let b = c ?? 1
不推荐
var a: Int?
if b {
    a = 1
} else {
    a = 2
}

集合

优先使用系统库提供的方法

var nums = []

nums.count == 0 // 推荐
nums.isEmpty // 不推荐

nums.first // 推荐
nums[0] // 不推荐

这块方法还很多,建议使用的时候多看看下相关api

优先使用filter/map/reduce等方法

不推荐
var nums = [1, 2, 3]

var result = []
for num in nums {
    if num < 3 {
        result.append(String(num))
    }
}
// result = ["1", "2"]
推荐
var nums = [1, 2, 3]

var result = nums.filter { $0 < 3 }.map { String($0) }
// result = ["1", "2"]

更少的局部变量,代码更加清晰,条理明确

考虑使用lazy

var nums = [1, 2, 3]

var result = nums.lazy.filter { $0 < 3 }.map { String($0) }
// result = ["1", "2"]

lazy会将处理优化为一次循环,提高性能

Struct

优先考虑使用Struct替代Class

Struct优点

  • 不需要管理引用计数
  • 不需要在堆上分配内存,更加轻量级 (PS: 某些大的结构体也会在堆上分配)

Struct替代不了的场景

  • 需要使用继承
  • 需要使用dealloc
  • 需要使用引用类型特性,对一个类实例进行多个引用
  • Struct修改属性,会生成一个新的Struct

Class

使用final修饰不能被继承的类

final class MyClass {
    
}

class MySubClass: MyClass {} // 编译错误

使用final修饰不能被重写的方法

class MyClass {
    final func method() {} // 不能被重写
}

可选值

不要使用!进行强解包

var num: Int?
let num2 = var! // 错误

Extension

使用Extension来组织代码

class MyViewController: UIViewController {
  // class stuff here
}

// MARK: - Private
extension: MyViewController {
    private func method() {}
}

// MARK: - UITableViewDataSource
extension MyViewController: UITableViewDataSource {
  // table view data source methods
}

// MARK: - UIScrollViewDelegate
extension MyViewController: UIScrollViewDelegate {
  // scroll view delegate methods
}
  • 可以将私有方法/父类方法/协议方法进行分离,更加清晰

for

Error Handing

不允许使用try!进行错误处理

try! test()

只有在错误不需要处理的场景,允许使用try?进行错误处理

try? test()

访问控制

使用private/fileprivate修饰私有propertymethod

private let num = 1
class MyClass {
    private var num: Int
}

使用private(set)修饰外部只读/内部可读写属性

class MyClass {
    private(set) var num = 1
}
let num = MyClass().num
MyClass().num = 2 // error

默认为internal
原则:尽可能保持属性/方法访问控制级别是好的编码习惯

不允许外部修改的变量,使用let修饰

内存

使用weak/unowned来处理循环引用

resource.request().onComplete { [weak self] response in
  guard let self = self else {
    return
  }
  let model = self.updateModel(response)
  self.updateUI(model)
}

resource.request().onComplete { [unowned self] response in
  let model = self.updateModel(response)
  self.updateUI(model)
}

weakunowned的区别

  • unowned不会自动设置为nil, 如果self已释放会触发错误. 只有在确定self一定会存在时才使用unowned
  • unowned的优点是self不会设置为可选值

格式

不要使用冒号

let name = 1
let name2 = 1; // error

符号之间添加空格

let name: Int = 1
var num: nums = [1, 2, 3]
func method(a: Int, _ b: Int?) -> Bool {
    return false
}

不要使用多个空格

除非必须,不要添加不需要的self.

func method() {
    num = 1 // 推荐
    self.num = 2 / 不推荐
}

换行

class MyClass {
    func method() {
    
    }
    
    func method2() {
    
    } 
}

extension MyClass {
    
}
  • 最多允许空一行

Swift的一些特性

使用defer

func method() {
    defer {
        // 会在method作用域结束的时候调用
    }
    
    // do
}

使用泛型

class MyClass {
    var a: T
}

let class = MyClass()

保持代码简洁

推荐

let nums: [Int] = []

不推荐

let nums = [Int]()
func test() -> [Int] {
    return 
}

注释

使用Command + /快捷键添加注释。

其他格式Xcode识别不出来

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