團(tuán)隊(duì)的Swift代碼規(guī)范售葡,參考Swift Style Guide和Swift 4.0 編碼規(guī)范,并根據(jù)團(tuán)隊(duì)實(shí)際需要做調(diào)整。
一缸匪、編碼格式
1.1 使用二元運(yùn)算符(+, -,==, 或->)的前后都需要添加空格
let value = 1 + 2
1.2 在逗號(hào)前面不添加空格类溢,后面加一個(gè)空格
let titleArray = [1, 2, 3, 4, 5]
1.3 在冒號(hào)前面不添加空格凌蔬,后面添加一個(gè)空格。
// 指定類型
let someViewController: SomeViewController
// 字典語法
let ninjaDictionary: [String: AnyObject] = [
"fightLikeDairyFarmer": false,
"disgusting": true
]
// 調(diào)用函數(shù)
someFunction(someArgument: "Kitten")
// 父類
class SomeViewController: UIViewController {
/* ... */
}
// 協(xié)議
extension SomeViewController: UITableViewDataSource {
/* ... */
}
1.3 左大括號(hào)不用另起一行
class SomeClass {
func someMethod() {
if x == y {
/* ... */
} else if x == z {
/* ... */
} else {
/* ... */
}
}
/* ... */
}
1.4 判斷語句中闯冷,只有一個(gè)判斷條件的時(shí)候砂心,不用加括號(hào)
if typeValue == 1 {
// code
}
1.5 在訪問枚舉類型時(shí),使用點(diǎn)語法
enum Direction {
case north
case south
case east
case west
}
let currentDirection = .west
1.6 遵守Xcode內(nèi)置的縮進(jìn)格式(格式快捷鍵:CTRL-i)蛇耀,當(dāng)聲明的一個(gè)函數(shù)需要跨多行時(shí)辩诞,推薦使用Xcode默認(rèn)格式。
// Xcode針對(duì)跨多行函數(shù)聲明縮進(jìn)
func myFunctionWithManyParameters(parameterOne: String,
parameterTwo: String,
parameterThree: String) {
// Xcode會(huì)自動(dòng)縮進(jìn)
print("\(parameterOne) \(parameterTwo) \(parameterThree)")
}
// Xcode針對(duì)多行 if 語句的縮進(jìn)
if myFirstVariable > (mySecondVariable + myThirdVariable) &&
myFourthVariable == .SomeEnumValue {
// Xcode會(huì)自動(dòng)縮進(jìn)
print("Hello, World!")
}
1.7 view controller的方法順序纺涤,根據(jù)生命周期排列躁倒。且在viewWillAppear、viewDidAppear中洒琢,需要先調(diào)用super方法秧秉。在viewWillDisappear、viewDidDisappear中衰抑,需最后調(diào)用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...
二象迎、命名規(guī)范
2.1 常量,變量呛踊,函數(shù)砾淌,方法的命名規(guī)則使用小駝峰規(guī)則,首字母小寫谭网,類型名使用大駝峰規(guī)則汪厨,首字母大寫。
class MyClass: class {
let myImageView: UIImageView
let myName: String
}
2.2 當(dāng)命名里出現(xiàn)縮寫詞時(shí)愉择,縮寫詞要么全部大寫劫乱,要么全部小寫织中,以首字母大小寫為準(zhǔn)。(服務(wù)器返回model的key除外)
let htmlString = "https://www.baidu.com"
let urlString: URLString
let userID: UserID
class HTMLModel {
//
}
2.3 bool類型命名時(shí)衷戈,使用is作為前綴(該條非強(qiáng)制狭吼,僅供參考)
var isMine: Bool = false
2.4 命名應(yīng)該具有描述性
// 推薦
class RoundAnimatingButton: UIButton { /* ... */ }
// 不推薦
class CustomButton: UIButton { /* ... */ }
2.5 不要簡(jiǎn)寫命名旁蔼,或用單個(gè)字母命名唤衫。(允許使用常見的縮寫,如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 如果原有命名不能明顯表明類型疲吸,則屬性命名內(nèi)要包括類型信息。
// 推薦
class ConnectionTableViewCell: UITableViewCell {
let personImageView: UIImageView
let animationDuration: NSTimeInterval
// 作為屬性名的firstName前鹅,很明顯是字符串類型磅氨,所以不用在命名里不用包含String
let firstName: String
let popupViewController: UIViewController
// 如果需要使用UIViewController的子類,如TableViewController, CollectionViewController, SplitViewController, 等嫡纠,需要在命名里標(biāo)名類型。
let popupTableViewController: UITableViewController
// 當(dāng)使用outlets時(shí), 確保命名中標(biāo)注類型延赌。
@IBOutlet weak var submitButton: UIButton!
@IBOutlet weak var emailTextField: UITextField!
@IBOutlet weak var nameLabel: UILabel!
}
// 不推薦
class ConnectionTableViewCell: UITableViewCell {
// 這個(gè)不是 UIImage, 不應(yīng)該以Image 為結(jié)尾命名除盏。
let personImage: UIImageView
// 這個(gè)不是String,應(yīng)該命名為 textLabel
let text: UILabel
// animation 不能清晰表達(dá)出時(shí)間間隔
// 建議使用 animationDuration 或 animationTimeInterval
let animation: NSTimeInterval
// transition 不能清晰表達(dá)出是String
// 建議使用 transitionText 或 transitionString
let transition: String
// 這個(gè)是ViewController挫以,不是View
let popupView: UIViewController
// 為了保持一致性者蠕,建議把類型放到變量的結(jié)尾,而不是開始掐松,如submitButton
@IBOutlet weak var btnSubmit: UIButton!
@IBOutlet weak var buttonSubmit: UIButton!
// 在使用outlets 時(shí)踱侣,變量名內(nèi)應(yīng)包含類型名,或其他能表達(dá)類型含義的單詞大磺。
// 這里建議使用 firstNameLabel
@IBOutlet weak var firstName: UILabel!
}
2.7 數(shù)組的名稱抡句,推薦使用元素的復(fù)數(shù)命名。
// 推薦
var entities: [SPEntity] = []
// 不推薦
var entityList: [SPEntity] = []
三杠愧、語法規(guī)范
3.1 可選類型拆包取值時(shí)待榔,使用if let 判斷
if let data = result.data {
// code
}
3.2 多個(gè)可選類型拆包取值時(shí),將多個(gè)if let 判斷合并
if let name = person.name, let age = person.age {
// code
}
3.3 盡量不要使用 as! 或 try!(除非可以確定不會(huì)出現(xiàn)異常)
// 使用if let as流济?
if let name = person.name as? String {
// code
}
3.4 當(dāng)對(duì)外接口不兼容時(shí)锐锣,使用@available(iOS x.0, *) 標(biāo)明接口適配的起始系統(tǒng)版本號(hào)
@available(iOS 8.0, *)
func myFunction() {
// code
}
3.5 盡可能的多使用let,少使用var绳瘟。
3.6 當(dāng)拆包取值時(shí)雕憔,使用和被拆包取值變量相同的名稱。
guard let myVariable = myVariable else {
return
}
3.7 在創(chuàng)建類常量的時(shí)候糖声,使用 static 關(guān)鍵詞修飾斤彼。
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 當(dāng)需要判斷變量是否是nil翁潘,但又不需要訪問變量值的時(shí)候趁冈,推薦直接把它跟nil做比較。
// 推薦
if someOptional != nil {
// do something
}
// 不推薦
if let _ = someOptional {
// do something
}
四拜马、注釋
對(duì)于寫代碼渗勘,注釋就是解釋。除非在非常必要的時(shí)候進(jìn)行適當(dāng)?shù)淖⑨屃┟В駝t只會(huì)增加閱讀代碼“噪聲”旺坠。
盡量用注釋說明why(為什么這里代碼要這么寫),而不是what(這里代碼寫的是什么)