设为首页 加入收藏

TOP

万字长文详解如何使用Swift提高代码质量(三)
2023-07-23 13:24:53 】 浏览:510
Tags:文详解 何使用 Swift 高代码

Object结构同时只会有一个值存在:

优化前

class Object {
    var name: Int?
    var num: Int?
}


优化后

  • 降低内存占用 - 枚举关联类型的大小取决于最大的关联类型大小
  • 逻辑更清晰 - 使用enum相比大量使用if/else逻辑更清晰
enum CustomType {
    case name(String)
    case num(Int)
}


减少var属性

使用计算属性

使用计算属性可以减少多个变量同步带来的潜在bug。

不推荐

class model {
  var data: Object?
  var loaded: Bool
}
model.data = Object()
loaded = false


推荐

class model {
  var data: Object?
  var loaded: Bool {
    return data != nil
  }
}
model.data = Object()


提示:计算属性因为每次都会重复计算,所以计算过程需要轻量避免带来性能问题。

控制流

使用filter/reduce/map代替for循环

使用filter/reduce/map可以带来很多好处,包括更少的局部变量,减少模板代码,代码更加清晰,可读性更高。

不推荐

let nums = [1, 2, 3]
var result = []
for num in nums {
    if num < 3 {
        result.append(String(num))
    }
}
// result = ["1", "2"]


推荐

let nums = [1, 2, 3]
let result = nums.filter { $0 < 3 }.map { String($0) }
// result = ["1", "2"]


使用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
}


使用for where优化循环

for循环添加where语句,只有当where条件满足时才会进入循环

不推荐

for item in collection {
  if item.hasProperty {
    // ...
  }
}


推荐

for item in collection where item.hasProperty {
  // item.hasProperty == true,才会进入循环
}


使用defer

defer可以保证在函数退出前一定会执行。可以使用defer中实现退出时一定会执行的操作例如资源释放等避免遗漏。

func method() {
    lock.lock()
    defer {
        lock.unlock()
        // 会在method作用域结束的时候调用
    }
    // do
}


字符串

使用"""

在定义复杂字符串时,使用多行字符串字面量可以保持原有字符串的换行符号/引号等特殊字符,不需要使用``进行转义。

let quotation = """
The White Rabbit put on his spectacles.  "Where shall I begin,
please your Majesty?" he asked.

"Begin at the beginning," the King said gravely, "and go on
till you come to the end; then stop."
"""


提示:上面字符串中的""和换行可以自动保留。

使用字符串插值

使用字符串插值可以提高代码可读性。

不推荐

let multiplier = 3
let message = String(multiplier) + "times 2.5 is" + String((Double(multiplier) * 2.5))


推荐

let multiplier = 3
let message = "(multiplier) times 2.5 is (Double(multiplier) * 2.5)"


集合

使用标准库提供的高阶函数

不推荐

var nums = []
nums.count == 0
nums[0]


推荐

var nums = []
nums.isEmpty
nums.first


访问控制

Swift中默认访问控制级别为internal。编码中应当尽可能减小属性/方法/类型的访问控制级别隐藏内部实现。

提示:同时也有利于编译器进行优化。

使用private/fileprivate修饰私有属性方法

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 // 会编译报错


函数

使用参数默认值

使用参数默认值,可以使调用方传递更少的参数。

不推荐

func test(a: Int, b: String?, c: Int?) {
}
test(1, nil, nil)


推荐

func test(a: Int, b: String? = nil, c: Int? = nil) {
}
test(1)


提示:相比ObjC参数默认值也可以让我们定义更少的方法。

限制参数数量

当方法参数过多时考虑使用自定义类型代替。

不推荐

func f(a: Int, b: Int, c: Int, d: Int, e: Int, f: Int) {
}


推荐

struct Params {
    let a, b, c, d, e, f: Int
}
func f(params: Params) {
}


使用@discardableResult

某些方法使用方并不一定会处理返回值,可以考虑添加@discardableResult标识提示Xcode允许不处理返回值不进行warning提示。

// 上报方法使用方不关心是否成功
func report(id: String) -> Bool {} 

@discardableResult func report2(id: String) -> Bool {}

report("1") // 编译器会警告
report2("1") // 不处理返回值编译器不会警告


元组

避免过长的元组

元组虽然具有类型信息,但是并不包含变量名信息,使用方并不清晰知道变量的含义。所以当元组数量过多时考虑使用自定义类型代替。

func test() -> (Int, Int, Int) {

}

let (a, b, c) = tes
首页 上一页 1 2 3 4 5 6 下一页 尾页 3/6/6
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇最近几天 下一篇给我两分钟的时间:微博风格九宫..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目