@Rookie
2022-06-22T15:29:43.000000Z
字数 5730
阅读 1934
iOS开发
enum Planet {
case mercury, venus, earth, mars, jupiter, saturn, uranus, neptune
}
struct Person {
var mobileNo: String
}
根据苹果接口设计指导准则,协议名称用来描述一些东西是什么的时候是名词,例如:Collection, WidgetFactory。若协议名称用来描述能力应该以 -ing, -able, 或 -ible 结尾,例如:Equatable, Resizing。
import SomeModule
let myClass = SomeModule.UsefulClass()
在定义委托方法时,第一个未命名参数应是委托数据源。
正确代码:
func namePickerView(_ namePickerView: NamePickerView, didSelectName name: String)
func namePickerViewShouldReload(_ namePickerView: NamePickerView) -> Bool
错误代码:
func didSelectName(namePicker: NamePickerViewController, name: String)
func namePickerShouldReload() -> Bool
泛型类参数应具有描述性,遵守“大骆驼命名法”。如果一个参数名没有具体的含义,可以使用传统单大写字符,如T, U, 或V等。
正确代码:
struct Stack<Element>{ ... }
func writeTo <Target: OutputStream>(to Target: inout Target)
func swap(_ a: inout T, _ b: inout T)
错误代码:
struct Stack<T>{ ... }
func write<target: OutputStream> (to target: inout target)
func swap<Thing>(_ a: inout Thing, _ b: inout Thing)
尽量使用类型推断以减少多余的冗余类型信息,例如:
正确的写法:
let currentLocation = Location()
错误的写法:
let currentLocation: Location = Location()
class BoardLocation {
let row: Int, column: Int
init(row: Int, column: Int) {
self.row = row
self.column = column
let closure = {
print(self.row)
}
}
}
static
。使用static
修饰常量可以允许他们在被引用的时候不需要实例化类型。
struct PhysicsModel {
static var speedOfLightInAVacuum = 299_792_458
}
class Spaceship {
static let topSpeed = PhysicsModel.speedOfLightInAVacuum
var speed: Double
func fullSpeedAhead() {
speed = Spaceship.topSpeed
}
}
正确代码:
class Example {
var age: UInt32 {
return arc4random()
}
}
错误代码:
class Example {
var age: UInt32 {
get {
return arc4random()
}
}
}
class Person {
var age: Int {
get {
return Int(arc4random())
}
set {
print("That's not your age.")
}
}
}
Swift中单例很简单,Swift 的 runtime 会保证单例的创建并且采用线程安全的方式访问:
class ControversyManager {
static let sharedInstance = ControversyManager()
}
单例通常只需要访问"sharedInstance"的静态属性,除非你有不得已的原因去重命名它。注意,不要用静态函数或者全局函数去访问你的单例。
可以使用do/try/catch
机制,避免使用try!
和try?
?
!
用 [weak self] 和 guard let strongSelf = self else { return } 模式扩展生命周期。用 [weak self] 比 [unowned self] 更好。
正确代码:
resource.request().onComplete { [weak self] response in
guard let strongSelf = self else { return }
let model = strongSelf.updateModel(response)
strongSelf.updateUI(model)
}
错误代码:
// might crash if self is released before response returns
resource.request().onComplete { [unowned self] response in
let model = self.updateModel(response)
self.updateUI(model)
}
// deallocate could happen between updating the model and updating UI
resource.request().onComplete { [weak self] response in
let model = self?.updateModel(response)
self?.updateUI(model)
}
Option+Command+/
// MARK:
分隔代码(类似于OC中的#pragma mark
) 遵守Xcode内置的缩进格式
优先使用Swift原生类型,可以根据需要使用Objective-C提供的方法,因为Swift提供了到Objective-C的桥接 。
正确代码:
let width = 120.0 // Double
let widthString = (width as NSNumber).stringValue // String
错误代码:
let width: NSNumber = 120.0 // NSNumber
let widthString: NSString=width.stringValue // NSString
当一个对象要实现协议一致性时,推荐使用 extension 隔离协议中的方法集,这样让相关方法和协议集中显示在一起,也简化了类支持一个协议和实现相关方法的流程。
正确代码:
class MyViewcontroller: UIViewController {
// 方法
}
extension MyViewcontroller: UITableViewDataSource {
// UITableViewDataSource 方法
}
extension MyViewcontroller: UIScrollViewDelegate {
// UIScrollViewDelegate 方法
}
错误代码:
class MyViewcontroller: UIViewController, UITableViewDataSource, UIScrollViewDelegate {
// 所有的方法
}
internal
这样的默认的修饰符。也不需要在重写一个方法时添加访问修饰符。final
修饰符
final class Circle: Shape {
var x: Int, y: Int
var radius: Double
var diameter: Double{
get {
returnradius * 2
}
set {
radius=newValue/2
}
}
init(x: Int, y: Int, radius: Double) {
self.x = x
self.y = y
self.radius = radius
}
convenience init(x: Int, y: Int, diameter: Double) {
self.init(x: x, y: y, radius: diameter/2)
}
func describe() -> String{
return"I am a circle at\(centerString())with an area of\(computeArea())"
}
override func computeArea() -> Double{
return M_PI * radius * radius
}
private func centerString()->String{
return "(\(x),\(y))"
}
}
for _ in 0..<3 {
print("Hello three times")
}
for(index, person) in attendeeList.enumerate() {
print("\(person)is at position #\(index)")
}
for index in 0.stride(from: 0, to: items.count, by: 2) {
print(index)
}
for index in (0...3).reverse() {
print(index)
}
错误代码:
var i=0
while i<3 {
print("Hello three times")
i+=1
}
var i=0
while i<3 {
let person = attendeeList[i]
print("\(person)is at position #\(i)")
i+=1
}
当编码遇到条件判断时,左边的距离是黄金路径或幸福路径,因为路径越短,速度越快。不要嵌套if循环,多个返回语句是可以的。guard 就为此而生的。
正确代码:
func computeFFT(context: Context?, inputData: InputData?) throws -> Frequencies {
guard let context = context else {throwFFTError.NoContext }
guard let inputData = inputData else { throwFFTError.NoInputData }
//计算frequencies
return frequencies
}
错误代码:
func computeFFT(context: Context?, inputData: InputData?) throws -> Frequencies {
if let context = context {
if let inputData = inputData {
// 计算frequencies
return frequencies
} else {
throwFFTError.NoInputData
}
} else {
throwFFTError.NoContext
}
}
当有多个条件需要用 guard 或 if let 解包,可用复合语句避免嵌套。
guard let number1=number1, number2=number2, number3=number3 else{
fatalError("impossible")
}
// 处理number
//对空的数据和字典,使用类型注解
var names: [String] = []
var lookup: [String: Int] = [:]
var deviceModels: [String]
var employees: [Int:String]
var faxNumber: Int?
自由函数不依附于任何类或类型,应该节制地使用。
正确代码:
let sorted = items.mergeSort() // 易发现性
rocket.launch() // 可读性
错误代码:
let sorted = mergeSort(items)// 不易被发现
launch(&rocket)
天然的自由函数:
let value = max(x,y,z) // another free function that feels natural
参考链接:
最详尽的 Swift 代码规范指南
Swift 3.0 编码规范
17条 Swift 最佳实践规范
一份比较通用的iOS代码规范,包括Objective-C和Swift
Swift 编码规范(中文)