待更新
文件
- 首字母请用大写
- 使用
MyClass+Additions
的格式添加Extension
功能
Additions
可以自由定义
-
swift
文件不要添加PG
前缀。
swift会根据模块名作为命名空间。转换后类名为
pgOrderModule.ViewController
命名
enum MyEnum {}
struct MyStruct {}
class MyClass {
var myNum: Int = 1
func myMethod() {}
}
typealias MyClass2 = MyClass
- 类型使用
大写
开头 -
property
和method
使用小写开头,驼峰格式
基础组件,为了防止重名,建议用自己的模块作为前缀
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
修饰私有property
和method
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)
}
weak
和unowned
的区别
-
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
识别不出来