
注意:代码中存在换行和缩进不规范的问题
命名规范
-
通用
- 禁止使用拼音命名
- 多个相似命名中禁止出现类似
lab1、lab2、lab3
的情况 - 尽量避免“简称”和“缩略词”,通用缩略词应该整体大写或整体小写
- 使用驼峰式命名方式,命名使用小写字母开头,常量最好使用k开头
推荐:
private let maximumWidgetCount = 100
class WidgetContainer {
var widgetButton: UIButton
let widgetHeightPercentage = 0.85
}
let urlString: URLString
let userID: UserID
不推荐:
let MAX_WIDGET_COUNT = 100
class app_widgetContainer {
var wBut: UIButton
let wHeightPct = 0.85
}
let uRLString: UrlString
let userId: UserId
- 命名是做到见名知意,尽量少使用全局变量
- 一个变量有且只有一个功能,尽量不要把一个变量作为多种用途
- 每个枚举值用小写字母开始
enum Shape {
case rectangle
case square
case rightTriangle
case equilateralTriangle
}
-
文件
- 工程文件命名禁止使用中文,首字母大写
- 资源文件命名(图片、文件等),首字母小写,且统一家里在资源文件中
- 创建新文件夹时必须保证工程目录与finder中的文件目录统一,且在工程中一般使用group
格式规范
-
函数
- 函数尽量控制入参数量,最好有必要的入参,尽量少使用无入参方法名
- 单个方法体不应超过100行,超过100行需重构
- 方法与方法之间需空行,方法内的局部变量和方法的第一条语句之间需空行
- 当调用的函数有多个参数时,每一个参数另起一行,并比函数名多一个缩进
-
注释
- 文档注释、块注释或单行注释之前,引用包注释可以不用空行
- 变量注释尽量写在变量的后面,对齐
- 实现文件中.函数的注释用
#MARK - description -
- 代码难以理解处添加注释
- 对于负责的类,在描述类的使用方法时可以添加一些合适的例子,请注意Swift注释是支持 MarkDown 语法的
/**
##功能列表
这个类提供下一下很赞的功能,如下:
- 功能 1
- 功能 2
- 功能 3
## 例子
这是一个代码块使用四个空格作为缩进的例子。
let myAwesomeThing = MyAwesomeClass()
myAwesomeThing.makeMoney()
## 警告
使用的时候总注意以下几点
1. 第一点
2. 第二点
3. 第三点
*/
class MyAwesomeClass {
/* ... */
}
-
代码的排列
- 类遵循代理,写在
MyClass{}
的下方,使用Extension
, 例如:extension MyClass: UITableViewDelegate{}
推荐:
class MyViewcontroller: UIViewController {
// class stuff here
}
// MARK: - UITableViewDataSource
extension MyViewcontroller: UITableViewDataSource {
// table view data source methods
}
// MARK: - UIScrollViewDelegate
extension MyViewcontroller: UIScrollViewDelegate {
// scroll view delegate methods
}
不推荐:
class MyViewcontroller: UIViewController, UITableViewDataSource, UIScrollViewDelegate {
// all methods
}
- 控制器之间的跳转方法写在
MyClass
的作用域的最后 - 构造方法和生命周期写在成员变量的下方
- 对
UIKit view controllers
,将lifecycle
,custom accessors
,and IBAction
等方法单独放在一个class extension
中 - 无用的code ,包括 Xcode 注释都应该被移除。空方法应该被移除
推荐:
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return Database.contacts.count
}
不推荐:
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return Database.contacts.count
}
- 可以用命令
Ctrl+I
重新排列代码 -
其他
- 运算符与变量间的空格
- 一元运算符与变量之间无空格,二元运算符与变量之间必须有空格
!bValue
~iValue
++iCount
*strSource
&fSum
fWidth = 5 + 5
fLength = fWidth * 2
fHeight = fWidth + fLength
- if语句
- 必须列出所有分支(穷举所有情况),每一个分支必须给出明确的结果
- 连续分支间使用
if else
连接
推荐:
if count < 3 {
copyString = "Hello"
}else{
copyString = ""
}
不推荐:
if count < 3 {
copyString = "Hello"
}
var weight: Int = 30
if weight >= 10 {
//TODO
}
if weight < 10 {
//TODO
}
- 不要使用过多的分支,善于使用`return`提前返回错误
推荐:
func customMethod(){
if x < 0 {
return
}
//TODO
}
guard n.isNumber else {
return
}
// Use n here
不推荐:
func customMethod(){
if x >= 0 {
//TODO
}
}
- 多个条件判断时,不要多个if嵌套,用 guard
推荐:
func computeFFT(context: Context?, inputData: InputData?) throws -> Frequencies {
guard let context = context else { throw FFTError.noContext }
guard let inputData = inputData else { throw FFTError.noInputData }
// use context and input to compute the frequencies
return frequencies
}
不推荐:
func computeFFT(context: Context?, inputData: InputData?) throws -> Frequencies {
if let context = context {
if let inputData = inputData {
// use context and input to compute the frequencies
return frequencies
} else {
throw FFTError.noInputData
}
} else {
throw FFTError.noContext
}
}
- 如果需要把访问修饰符放到第一个位置
// 推荐
private static let kMyPrivateNumber: Int
// 不推荐
static private let kMyPrivateNumber: Int
- 声明单例属性可以通过下面方式进行
class PirateManager {
static let sharedInstance = PirateManager()
/* ... */
}
- 避免使用
self
去调用属性或方法,仅在初始化方法的参数名和属性名相同时用self
class BoardLocation {
let row: Int, column: Int
init(row: Int, column: Int) {
self.row = row
self.column = column
let closure = {
print(self.row)
}
}
}
- 如果一个计算属性的返回值很简单,可以省去 get{}。有 set{} 就一定要有 get{}
推荐:
var diameter: Double {
return radius * 2
}
var myGreatProperty: Int {
return 4
}
subscript(index: Int) -> T {
return objects[index]
}
不推荐:
var diameter: Double {
get {
return radius * 2
}
}
var myGreatProperty: Int {
get {
return 4
}
}
subscript(index: Int) -> T {
get {
return objects[index]
}
}
后记:
- 初版比较粗糙,文档会在之后更多的实践中增加和修改
- 如有错误或不当的地方欢迎留言指正,在此感谢!
参考文档:
https://github.com/github/swift-style-guide
http://www.jianshu.com/p/288ea00dcfcf
网友评论