Swift编码规范(目前swift 4.2,持续更新)

参考项目实际、官方文档、raywenderlich(传送门)等大神总结的swift语言的编码规范,适应目前swift 4.2,笔者会不定期更新,欢迎指正补充
约定,请尽量确保代码编译不残留warning,这有可以规避很多问题

文章目录

命名规范

常量,变量,函数,方法的命名规则使用小驼峰规则,首字母小写;

类别名称(类、结构体、枚举和协议)使用大驼峰规则,首字母大写。

正例
let maximumWidgetCount = 100
class WidgetContainer {
	var widgetButton: UIButton
	let widgetHeightPercentage = 0.85
}
反例
let MAX_WIDGET_COUNT = 100
class app_widgetContainer {
	var wBut: UIButton
	let wHeightPct = 0.85
}

缩写

缩写和简写只能使用常用的或者约定俗成的缩写,缩写和简写中的所有字符的大小写要一致

正例
let urlString: URLString
let userID: UserID
反例
let uRLString: UrlString
let userId: UserId

bool类型变量命名时,建议以is作为前缀

正例
var isMine: Bool = false

代理

在创建自定义代理方法时,第一个未命名的参数应该是代理源

正例
func namePickerView(_ namePickerView: NamePickerView, didSelectName name: String)
func namePickerViewShouldReload(_ namePickerView: NamePickerView) -> Bool
反例
func didSelectName(namePicker: NamePickerViewController, name: String)
func namePickerShouldReload() -> Bool

使用类型推断的上下文

推荐使用编译器推断的上下文来编写更加简短清晰的代码。不作为规范强制。

正例
let selector = #selector(viewDidLoad)
view.backgroundColor = .red
let toView = context.view(forKey: .to)
let view = UIView(frame: .zero)
反例
let selector = #selector(ViewController.viewDidLoad)
view.backgroundColor = UIColor.red
let toView = context.view(forKey: UITransitionContextViewKey.to)
let view = UIView(frame: CGRect.zero)

使用懒加载来细致地控制对象的生命周期,对于想实现延迟加载视图的UIViewController特别有用

// MARK: - 懒加载
private lazy var tableView: UITableView = {
	let tableView = UITableView.init(frame: .zero, stype: .plain)
	tableView.separatorStyle = .none
	tableView.rowHeight = UITableViewAutomaticDimension
	tableView.estimatedRowHeight = 200
	tableView.dataSource = self
	tableView.delegate = self
	tableView.register(UINib(nibName: homeListCell, bundle: nil), forCellReuseIdentifier: homeListCell)
	return tableView
}()

语法规范

最少化import

仅导入所需要的模块,例如,当导入Foundation能满足功能时不要导入UIKit;同理,当导入UIKit后,不要再导入Foundation

正例
import UIKit
var view: UIView
var deviceModels: [String]
import Foundation
var deviceModels: [String]
反例
import UIKit
import Foundation
var view: UIView
var deviceModels: [String]
import UIKit
var deviceModels: [String]

可选类型拆包取值时,先使用if let判断

if let data = result.data {
	// do someting
}

多个可选类型拆包取值时,将多个if let 判断合并

if let name = persion.name, let age = person.age {
	// do something
}

尽量不要使用 as! 或 try! ,对于可选类型Optional多使用as? ,?? 可以给变量设置默认值

// 使用if let as? 判断
if let name = person.name as? String {
	// doSomething
}
// 给name变量设置默认值
var name = person.name ?? ""

数组和字典变量定义时需要标明泛型类型,并使用更简洁清晰的语法

var names: [String] = []
var values: [String: Int] = [:]
var person: [String: Any] = [:]

常量定义,建议尽可能定义在类型里面,避免污染全局命名空间,如果是其他地方有可能复用的可以定义在类型外面

static let homeListCell = "HomeListCell"

class HomeListCell: UITableViewCell {
	static let kHomeCellHeight = 80.0
}

优先使用guard来确保条件判断的简短

func login(with username: String?, password: String?) throws -> LoginError {
	guard let username = username else {
		throw .noUsername
	}
	guard let password = password else {
		throw .noPassword
	}
	// doSomething
}

使用for in表达式进行遍历

for index in (0...10) {
	print(index)
}

当接口版本不兼容时,使用@available(iOS x.0, *)来表明接口适配的起始系统版本

@available(iOS 8.0, *)
func myFunction() {
	// doSomething
}

编码格式

语句结束使用回车符,不使用分号

使用二元运算符(+ - * / = == > <等)的前后都需要添加空格

let value = 1 + 2

逗号后面加一个空格

let titleArray = [1, 2, 3, 4, 5]

缩进

方法、if、switch等左大括号不要另起一行,跟随语句放在行末,前置1空格;右大括号独占一行,除非后面跟着统一语句的剩余部分(do while、if else等)

func myFunction {
	if ... {
		...
	} else {
		...
	}
}

判断语句不用加括号

if typeValue == 1 {
	...
}

尽量不适用self,除非形参与属性同名

func setPerson(name: String, pAge: Int) {
	self.name = name
	age = pAge
}

访问枚举类型时,使用更简洁的点语法

enum Direction {
	case north
	case south
	case east
	case west
}
let currentDerection = .east

应删除未使用的代码,包括Xcode末班代码和占位符注释,只实现超类的代理方法等(如未使用的UIApplicationDelegate方法)

正例
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
	return Database.contacts.count
}
反例
override func didReceiveMemoryWarning() {
	super.didReceiveMemoryWarning()
	// Dispose of any resources that can be recreated.
}

override func numberOfSections(in 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
}

注释

一般的,尽量通过清晰的架构逻辑,好的符号命名来提高代码可读性;需要的时候,才辅以注释说明。
注释是为了帮助阅读者快速读懂代码,所以要从读者的角度出发,按需注释。
注释内容要简洁、明了、无二义性,信息全面且不冗余。
注释跟代码一样重要。
写注释时要换位思考,用注释去表达此时读者真正需要的信息。在代码的功能、意图层次上进行注释,即注释解释代码难以表达的意图,不要重复代码信息。
修改代码时,也要保证其相关注释的一致性。只改代码,不改注释是一种不文明行为,破坏了代码与注释的一致性,让阅读者迷惑、费解,甚至误解。

推荐使用// MARK: - ,按功能、协议、代理等分组

// MARK: - UITableViewDelegate

// MARK: - Action

// MARK: - Request

文件头注释必须包含版权许可、功能说明、作者和创建日期

函数头注释

推荐使用Xcode注释快捷键(⌘⌥/)

/// <#Description#>
///
/// - Parameters:
///   - admin: <#admin description#>
///   - passWord: <#passWord description#>
func registHilinkGateWay(admin : String , passWord : String) -> Void {
}

代码注释

代码注释放于对应代码的上方或者右边

注释符与注释内容间空1格;右置注释与前面代码空1格;代码上方的注释,应与对应代码保持一样的缩进。

	// 单行注释
	doSomething()
	
	// 多行注释
	// 第二行
	doSomething()
	
	doSomething() // 右置注释

函数

函数设计

避免函数过长,建议函数不超过50行(去空行去注释)

避免函数的代码块嵌套过深,建议不要超过4层

函数的代码块嵌套深度指的是函数中的代码控制块(如:if、for、while、switch等)之间互相包含的深度。
推荐使用卫语句来减少if相关的嵌套层级

优化前
func handleReceive(receive: String) {
	if receive {
		let type = receive.type
		if type != UNKNOWN {
			// doSomething
		}
	}
}
优化后
func handleReceive(receive: String) {
	if !receive { // 使用'卫语句'
		return
	}
	
	let type = receive.type
	if type != UNKNOWN {
		// doSomething
	}
}

函数的参数建议不超过5个

闭包

为避免循环引用,闭包内使用弱引用;为避免弱引用被提前释放,多次引用前使用强引用转换。

resource.request().onComplete {[weak self] response in
	guard let strongSelf = self else { return } // 强引用显式地延长self的生命周期
	let model = strongSelf.updateModel(response)
	strongSelf.updateUI(model)
}

resource.request().onComplete {[weak self] response in
	guard let `self` = self else { return } // 推荐使用swift语法糖``
	let model = self.updateModel(response)
	self.updateUI(model)
}

当闭包时函数的最后一个参数,采用尾随闭包写法

UIView.animateWithDuration(1.0) {
	self.myView.alpha = 0
}

当单个闭包表达式上下文清晰时,使用隐式的返回值

arrayList.sort { a,b in
	a > b
}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值