Multiline Arguments
标识符 |
默认开启 |
支持自动更正 |
类别 |
分析仪 |
最低swift编译版本 |
multiline_arguments |
否 |
否 |
style |
否 |
3.0.0 |
实参需要写在同一行或者每个一行。
示例
非触发
foo()
foo(
)
foo { }
foo {
}
foo(0)
foo(0, 1)
foo(0, 1) { }
foo(0, param1: 1)
foo(0, param1: 1) { }
foo(param1: 1)
foo(param1: 1) { }
foo(param1: 1, param2: true) { }
foo(param1: 1, param2: true, param3: [3]) { }
foo(param1: 1, param2: true, param3: [3]) {
bar()
}
foo(param1: 1,
param2: true,
param3: [3])
foo(
param1: 1, param2: true, param3: [3]
)
foo(
param1: 1,
param2: true,
param3: [3]
)
触发
foo(0,
param1: 1, ↓param2: true, ↓param3: [3])
foo(0, ↓param1: 1,
param2: true, ↓param3: [3])
foo(0, ↓param1: 1, ↓param2: true,
param3: [3])
foo(
0, ↓param1: 1,
param2: true, ↓param3: [3]
)
补充
简单讲 arguments指实参 parameters指形参
parameters和arguments的区别
Mutiline Function Chains
标识符 |
默认开启 |
支持自动更正 |
类别 |
分析仪 |
最低swift编译版本 |
multiline_function_chains |
否 |
否 |
style |
否 |
3.0.0 |
链式调用需要写在同一行或者每个一行。
示例
非触发
let evenSquaresSum = [20, 17, 35, 4].filter { $0 % 2 == 0 }.map { $0 * $0 }.reduce(0, +)
let evenSquaresSum = [20, 17, 35, 4]
.filter { $0 % 2 == 0 }.map { $0 * $0 }.reduce(0, +)",
let chain = a
.b(1, 2, 3)
.c { blah in
print(blah)
}
.d()
let chain = a.b(1, 2, 3)
.c { blah in
print(blah)
}
.d()
let chain = a.b(1, 2, 3)
.c { blah in print(blah) }
.d()
let chain = a.b(1, 2, 3)
.c(.init(
a: 1,
b, 2,
c, 3))
.d()
self.viewModel.outputs.postContextualNotification
.observeForUI()
.observeValues {
NotificationCenter.default.post(
Notification(
name: .ksr_showNotificationsDialog,
userInfo: [UserInfoKeys.context: PushNotificationDialog.Context.pledge,
UserInfoKeys.viewController: self]
)
)
}
let remainingIDs = Array(Set(self.currentIDs).subtracting(Set(response.ids)))
self.happeningNewsletterOn = self.updateCurrentUser
.map { $0.newsletters.happening }.skipNil().skipRepeats()
触发
let evenSquaresSum = [20, 17, 35, 4]
.filter { $0 % 2 == 0 }↓.map { $0 * $0 }
.reduce(0, +)
let evenSquaresSum = a.b(1, 2, 3)
.c { blah in
print(blah)
}↓.d()
let evenSquaresSum = a.b(1, 2, 3)
.c(2, 3, 4)↓.d()
let evenSquaresSum = a.b(1, 2, 3)↓.c { blah in
print(blah)
}
.d()
a.b {
// ““
}↓.e()
Multiline Parameters
标识符 |
默认开启 |
支持自动更正 |
类别 |
分析仪 |
最低swift编译版本 |
multiline_parameters |
否 |
否 |
style |
否 |
3.0.0 |
形参需要写在同一行或者每个一行。
示例
非触发
func foo() { }
func foo(param1: Int) { }
func foo(param1: Int, param2: Bool) { }
func foo(param1: Int, param2: Bool, param3: [String]) { }
func foo(param1: Int,
param2: Bool,
param3: [String]) { }
func foo(_ param1: Int, param2: Int, param3: Int) -> (Int) -> Int {
return { x in x + param1 + param2 + param3 }
}
static func foo() { }
static func foo(param1: Int) { }
static func foo(param1: Int, param2: Bool) { }
static func foo(param1: Int, param2: Bool, param3: [String]) { }
static func foo(param1: Int,
param2: Bool,
param3: [String]) { }
protocol Foo {
func foo() { }
}
protocol Foo {
func foo(param1: Int) { }
}
protocol Foo {
func foo(param1: Int, param2: Bool) { }
}
protocol Foo {
func foo(param1: Int, param2: Bool, param3: [String]) { }
}
protocol Foo {
func foo(param1: Int,
param2: Bool,
param3: [String]) { }
}
protocol Foo {
static func foo(param1: Int, param2: Bool, param3: [String]) { }
}
protocol Foo {
static func foo(param1: Int,
param2: Bool,
param3: [String]) { }
}
protocol Foo {
class func foo(param1: Int, param2: Bool, param3: [String]) { }
}
protocol Foo {
class func foo(param1: Int,
param2: Bool,
param3: [String]) { }
}
enum Foo {
func foo() { }
}
enum Foo {
func foo(param1: Int) { }
}
enum Foo {
func foo(param1: Int, param2: Bool) { }
}
enum Foo {
func foo(param1: Int, param2: Bool, param3: [String]) { }
}
enum Foo {
func foo(param1: Int,
param2: Bool,
param3: [String]) { }
}
enum Foo {
static func foo(param1: Int, param2: Bool, param3: [String]) { }
}
enum Foo {
static func foo(param1: Int,
param2: Bool,
param3: [String]) { }
}
struct Foo {
func foo() { }
}
struct Foo {
func foo(param1: Int) { }
}
struct Foo {
func foo(param1: Int, param2: Bool) { }
}
struct Foo {
func foo(param1: Int, param2: Bool, param3: [String]) { }
}
struct Foo {
func foo(param1: Int,
param2: Bool,
param3: [String]) { }
}
struct Foo {
static func foo(param1: Int, param2: Bool, param3: [String]) { }
}
struct Foo {
static func foo(param1: Int,
param2: Bool,
param3: [String]) { }
}
class Foo {
func foo() { }
}
class Foo {
func foo(param1: Int) { }
}
class Foo {
func foo(param1: Int, param2: Bool) { }
}
class Foo {
func foo(param1: Int, param2: Bool, param3: [String]) { }
}
class Foo {
func foo(param1: Int,
param2: Bool,
param3: [String]) { }
}
class Foo {
class func foo(param1: Int, param2: Bool, param3: [String]) { }
}
class Foo {
class func foo(param1: Int,
param2: Bool,
param3: [String]) { }
}
class Foo {
class func foo(param1: Int,
param2: Bool,
param3: @escaping (Int, Int) -> Void = { _, _ in }) { }
}
class Foo {
class func foo(param1: Int,
param2: Bool,
param3: @escaping (Int) -> Void = { _ in }) { }
}
class Foo {
class func foo(param1: Int,
param2: Bool,
param3: @escaping ((Int) -> Void)? = nil) { }
}
class Foo {
class func foo(param1: Int,
param2: Bool,
param3: @escaping ((Int) -> Void)? = { _ in }) { }
}
class Foo {
class func foo(param1: Int,
param2: @escaping ((Int) -> Void)? = { _ in },
param3: Bool) { }
}
class Foo {
class func foo(param1: Int,
param2: @escaping ((Int) -> Void)? = { _ in },
param3: @escaping (Int, Int) -> Void = { _, _ in }) { }
}
class Foo {
class func foo(param1: Int,
param2: Bool,
param3: @escaping (Int) -> Void = { (x: Int) in }) { }
}
class Foo {
class func foo(param1: Int,
param2: Bool,
param3: @escaping (Int, (Int) -> Void) -> Void = { (x: Int, f: (Int) -> Void) in }) { }
}
触发
func ↓foo(_ param1: Int,
param2: Int, param3: Int) -> (Int) -> Int {
return { x in x + param1 + param2 + param3 }
}
protocol Foo {
func ↓foo(param1: Int,
param2: Bool, param3: [String]) { }
}
protocol Foo {
func ↓foo(param1: Int, param2: Bool,
param3: [String]) { }
}
protocol Foo {
static func ↓foo(param1: Int,
param2: Bool, param3: [String]) { }
}
protocol Foo {
static func ↓foo(param1: Int, param2: Bool,
param3: [String]) { }
}
protocol Foo {
class func ↓foo(param1: Int,
param2: Bool, param3: [String]) { }
}
protocol Foo {
class func ↓foo(param1: Int, param2: Bool,
param3: [String]) { }
}
enum Foo {
func ↓foo(param1: Int,
param2: Bool, param3: [String]) { }
}
enum Foo {
func ↓foo(param1: Int, param2: Bool,
param3: [String]) { }
}
enum Foo {
static func ↓foo(param1: Int,
param2: Bool, param3: [String]) { }
}
enum Foo {
static func ↓foo(param1: Int, param2: Bool,
param3: [String]) { }
}
struct Foo {
func ↓foo(param1: Int,
param2: Bool, param3: [String]) { }
}
struct Foo {
func ↓foo(param1: Int, param2: Bool,
param3: [String]) { }
}
struct Foo {
static func ↓foo(param1: Int,
param2: Bool, param3: [String]) { }
}
struct Foo {
static func ↓foo(param1: Int, param2: Bool,
param3: [String]) { }
}
class Foo {
func ↓foo(param1: Int,
param2: Bool, param3: [String]) { }
}
class Foo {
func ↓foo(param1: Int, param2: Bool,
param3: [String]) { }
}
class Foo {
class func ↓foo(param1: Int,
param2: Bool, param3: [String]) { }
}
class Foo {
class func ↓foo(param1: Int, param2: Bool,
param3: [String]) { }
}
class Foo {
class func ↓foo(param1: Int,
param2: Bool, param3: @escaping (Int, Int) -> Void = { _, _ in }) { }
}
class Foo {
class func ↓foo(param1: Int,
param2: Bool, param3: @escaping (Int) -> Void = { (x: Int) in }) { }
}
Multiple Closures with Trailing Closure
标识符 |
默认开启 |
支持自动更正 |
类别 |
分析仪 |
最低swift编译版本 |
multiple_closures_with_trailing_closure |
是 |
否 |
style |
否 |
3.0.0 |
有多个闭包作为参数的时候,不应该使用尾随闭包语法。
示例
非触发
foo.map { $0 + 1 }
foo.reduce(0) { $0 + $1 }
if let foo = bar.map({ $0 + 1 }) {
}
foo.something(param1: { $0 }, param2: { $0 + 1 })
UIView.animate(withDuration: 1.0) {
someView.alpha = 0.0
}
触发
foo.something(param1: { $0 }) ↓{ $0 + 1 }
UIView.animate(withDuration: 1.0, animations: {
someView.alpha = 0.0
}) ↓{ _ in
someView.removeFromSuperview()
}
补充
闭包
Swift闭包简单应用
Nesting
标识符 |
默认开启 |
支持自动更正 |
类别 |
分析仪 |
最低swift编译版本 |
nesting |
是 |
否 |
metrics |
否 |
3.0.0 |
类型嵌套最多一级,语句嵌套最多五级。
示例
非触发
class Class0 { class Class1 {} }
func func0() {
func func1() {
func func2() {
func func3() {
func func4() { func func5() {
}
}
}
}
}
}
struct Class0 { struct Class1 {} }
func func0() {
func func1() {
func func2() {
func func3() {
func func4() { func func5() {
}
}
}
}
}
}
enum Class0 { enum Class1 {} }
func func0() {
func func1() {
func func2() {
func func3() {
func func4() { func func5() {
}
}
}
}
}
}
enum Enum0 { enum Enum1 { case Case } }
触发
class A { class B { ↓class C {} } }
struct A { struct B { ↓struct C {} } }
func func0() {
func func1() {
func func2() {
func func3() {
func func4() { func func5() {
↓func func6() {
}
}
}
}
}
}
}
Nimble Operator
标识符 |
默认开启 |
支持自动更正 |
类别 |
分析仪 |
最低swift编译版本 |
nimble_operator |
否 |
是 |
idiomatic |
否 |
3.0.0 |
优先使用Nimble运算符而不是匹配函数
示例
非触发
expect(seagull.squawk) != "Hi!"
expect("Hi!") == "Hi!"
expect(10) > 2
expect(10) >= 10
expect(10) < 11
expect(10) <= 10
expect(x) === x
expect(10) == 10
expect(object.asyncFunction()).toEventually(equal(1))
expect(actual).to(haveCount(expected))
触发
↓expect(seagull.squawk).toNot(equal("Hi"))
↓expect(12).toNot(equal(10))
↓expect(10).to(equal(10))
↓expect(10).to(beGreaterThan(8))
↓expect(10).to(beGreaterThanOrEqualTo(10))
↓expect(10).to(beLessThan(11))
↓expect(10).to(beLessThanOrEqualTo(10))
↓expect(x).to(beIdenticalTo(x))
expect(10) > 2
↓expect(10).to(beGreaterThan(2))
补充
Swift 进阶开发指南:如何使用 Quick、Nimble 执行测试驱动开发(TDD)
No Extension Access Modifier
标识符 |
默认开启 |
支持自动更正 |
类别 |
分析仪 |
最低swift编译版本 |
no_extension_access_modifier |
否 |
否 |
idiomatic |
否 |
3.0.0 |
不要对Extension使用权限控制符
示例
非触发
extension String {}
extension String {}
触发
↓private extension String {}
↓public
extension String {}
↓open extension String {}
↓internal extension String {}
↓fileprivate extension String {}
No Fallthrough Only
标识符 |
默认开启 |
支持自动更正 |
类别 |
分析仪 |
最低swift编译版本 |
no_fallthrough_only |
是 |
否 |
idiomatic |
否 |
3.0.0 |
使用fallthrough
的case
语句至少要包含一句其他的语句
示例
非触发
switch myvar {
case 1:
var a = 1
fallthrough
case 2:
var a = 2
}
switch myvar {
case "a":
var one = 1
var two = 2
fallthrough
case "b": /* comment */
var three = 3
}
switch myvar {
case 1:
let one = 1
case 2:
// comment
var two = 2
}
switch myvar {
case MyFunc(x: [1, 2, YourFunc(a: 23)], y: 2):
var three = 3
fallthrough
default:
var three = 4
}
switch myvar {
case .alpha:
var one = 1
case .beta:
var three = 3
fallthrough
default:
var four = 4
}
let aPoint = (1, -1)
switch aPoint {
case let (x, y) where x == y:
let A = "A"
case let (x, y) where x == -y:
let B = "B"
fallthrough
default:
let C = "C"
}
switch myvar {
case MyFun(with: { $1 }):
let one = 1
fallthrough
case "abc":
let two = 2
}
触发
switch myvar {
case 1:
↓fallthrough
case 2:
var a = 1
}
switch myvar {
case 1:
var a = 2
case 2:
↓fallthrough
case 3:
var a = 3
}
switch myvar {
case 1: // comment
↓fallthrough
}
switch myvar {
case 1: /* multi
line
comment */
↓fallthrough
case 2:
var a = 2
}
switch myvar {
case MyFunc(x: [1, 2, YourFunc(a: 23)], y: 2):
↓fallthrough
default:
var three = 4
}
switch myvar {
case .alpha:
var one = 1
case .beta:
↓fallthrough
case .gamma:
var three = 3
default:
var four = 4
}
let aPoint = (1, -1)
switch aPoint {
case let (x, y) where x == y:
let A = "A"
case let (x, y) where x == -y:
↓fallthrough
default:
let B = "B"
}
switch myvar {
case MyFun(with: { $1 }):
↓fallthrough
case "abc":
let two = 2
}
补充
fallthrough
在case中之后的语句不会执行,转而执行下一个case
或者default
语句 属于流程控制的一部分
这里是官方文档
No Grouping Extension
标识符 |
默认开启 |
支持自动更正 |
类别 |
分析仪 |
最低swift编译版本 |
no_grouping_extension |
否 |
否 |
idiomatic |
否 |
3.0.0 |
不应该使用Extension来对同文件源码进行分组。
示例
非触发
protocol Food {}
extension Food {}
class Apples {}
extension Oranges {}
触发
enum Fruit {}
↓extension Fruit {}
↓extension Tea: Error {}
struct Tea {}
class Ham { class Spam {}}
↓extension Ham.Spam {}
extension External { struct Gotcha {}}
↓extension External.Gotcha {}
Notification Center Detachment
标识符 |
默认开启 |
支持自动更正 |
类别 |
分析仪 |
最低swift编译版本 |
notification_center_detachment |
是 |
否 |
lint |
否 |
3.0.0 |
当一个对象作为观察者时,需要在deinit
中移除
示例
非触发
class Foo {
deinit {
NotificationCenter.default.removeObserver(self)
}
}
class Foo {
func bar() {
NotificationCenter.default.removeObserver(otherObject)
}
}
触发
class Foo {
func bar() {
↓NotificationCenter.default.removeObserver(self)
}
}
补充
deinitialization
Number Separator
标识符 |
默认开启 |
支持自动更正 |
类别 |
分析仪 |
最低swift编译版本 |
number_separator |
否 |
是 |
style |
否 |
3.0.0 |
对于比较大的数字来讲,下划线分隔符应该作为千分位的分隔符
示例
非触发
let foo = -100
let foo = -1_000
let foo = -1_000_000
let foo = -1.000_1
let foo = -1_000_000.000_000_1
let binary = -0b10000
let binary = -0b1000_0001
let hex = -0xA
let hex = -0xAA_BB
let octal = -0o21
let octal = -0o21_1
let exp = -1_000_000.000_000e2
let foo = +100
let foo = +1_000
let foo = +1_000_000
let foo = +1.000_1
let foo = +1_000_000.000_000_1
let binary = +0b10000
let binary = +0b1000_0001
let hex = +0xA
let hex = +0xAA_BB
let octal = +0o21
let octal = +0o21_1
let exp = +1_000_000.000_000e2
let foo = 100
let foo = 1_000
let foo = 1_000_000
let foo = 1.000_1
let foo = 1_000_000.000_000_1
let binary = 0b10000
let binary = 0b1000_0001
let hex = 0xA
let hex = 0xAA_BB
let octal = 0o21
let octal = 0o21_1
let exp = 1_000_000.000_000e2
触发
let foo = ↓-10_0
let foo = ↓-1000
let foo = ↓-1000e2
let foo = ↓-1000E2
let foo = ↓-1__000
let foo = ↓-1.0001
let foo = ↓-1_000_000.000000_1
let foo = ↓-1000000.000000_1
let foo = +↓10_0
let foo = +↓1000
let foo = +↓1000e2
let foo = +↓1000E2
let foo = +↓1__000
let foo = +↓1.0001
let foo = +↓1_000_000.000000_1
let foo = +↓1000000.000000_1
let foo = ↓10_0
let foo = ↓1000
let foo = ↓1000e2
let foo = ↓1000E2
let foo = ↓1__000
let foo = ↓1.0001
let foo = ↓1_000_000.000000_1
let foo = ↓1000000.000000_1
Object Literal
标识符 |
默认开启 |
支持自动更正 |
类别 |
分析仪 |
最低swift编译版本 |
object_literal |
否 |
否 |
idiomatic |
否 |
3.0.0 |
优先使用object literal
来取代图像和颜色的初始化
示例
非触发
let image = #imageLiteral(resourceName: "image.jpg")
let color = #colorLiteral(red: 0.9607843161, green: 0.7058823705, blue: 0.200000003, alpha: 1)
let image = UIImage(named: aVariable)
let image = UIImage(named: "interpolated \(variable)")
let color = UIColor(red: value, green: value, blue: value, alpha: 1)
let image = NSImage(named: aVariable)
let image = NSImage(named: "interpolated \(variable)")
let color = NSColor(red: value, green: value, blue: value, alpha: 1)
触发
let image = ↓UIImage(named: "foo")
let color = ↓UIColor(red: 0.3, green: 0.3, blue: 0.3, alpha: 1)
let color = ↓UIColor(red: 100 / 255.0, green: 50 / 255.0, blue: 0, alpha: 1)
let color = ↓UIColor(white: 0.5, alpha: 1)
let image = ↓NSImage(named: "foo")
let color = ↓NSColor(red: 0.3, green: 0.3, blue: 0.3, alpha: 1)
let color = ↓NSColor(red: 100 / 255.0, green: 50 / 255.0, blue: 0, alpha: 1)
let color = ↓NSColor(white: 0.5, alpha: 1)
let image = ↓UIImage.init(named: "foo")
let color = ↓UIColor.init(red: 0.3, green: 0.3, blue: 0.3, alpha: 1)
let color = ↓UIColor.init(red: 100 / 255.0, green: 50 / 255.0, blue: 0, alpha: 1)
let color = ↓UIColor.init(white: 0.5, alpha: 1)
let image = ↓NSImage.init(named: "foo")
let color = ↓NSColor.init(red: 0.3, green: 0.3, blue: 0.3, alpha: 1)
let color = ↓NSColor.init(red: 100 / 255.0, green: 50 / 255.0, blue: 0, alpha: 1)
let color = ↓NSColor.init(white: 0.5, alpha: 1)
补充
Swift Literals
Be Literal
Opening Brace Spacing
标识符 |
默认开启 |
支持自动更正 |
类别 |
分析仪 |
最低swift编译版本 |
opening_brace |
是 |
是 |
style |
否 |
3.0.0 |
开口大括号前必须又一个空格,并且应该与声明位于同一行
示例
非触发
func abc() {
}
[].map() { $0 }
[].map({ })
if let a = b { }
while a == b { }
guard let a = b else { }
if
let a = b,
let c = d
where a == c
{ }
while
let a = b,
let c = d
where a == c
{ }
guard
let a = b,
let c = d
where a == c else
{ }
struct Rule {}
struct Parent {
struct Child {
let foo: Int
}
}
触发
func abc()↓{
}
func abc()
↓{ }
[].map()↓{ $0 }
[].map( ↓{ } )
if let a = b↓{ }
while a == b↓{ }
guard let a = b else↓{ }
if
let a = b,
let c = d
where a == c↓{ }
while
let a = b,
let c = d
where a == c↓{ }
guard
let a = b,
let c = d
where a == c else↓{ }
struct Rule↓{}
struct Rule
↓{
}
struct Rule
↓{
}
struct Parent {
struct Child
↓{
let foo: Int
}
}
Operator Usage Whitespace
标识符 |
默认开启 |
支持自动更正 |
类别 |
分析仪 |
最低swift编译版本 |
operator_usage_whitespace |
否 |
是 |
style |
否 |
3.0.0 |
运算符前后应当被空格包裹
示例
非触发
let foo = 1 + 2
let foo = 1 > 2
let foo = !false
let foo: Int?
let foo: Array<String>
let model = CustomView<Container<Button>, NSAttributedString>()
let foo: [String]
let foo = 1 +
2
let range = 1...3
let range = 1 ... 3
let range = 1..<3
#if swift(>=3.0)
foo()
#endif
array.removeAtIndex(-200)
let name = "image-1"
button.setImage(#imageLiteral(resourceName: "image-1"), for: .normal)
let doubleValue = -9e-11
let foo = GenericType<(UIViewController) -> Void>()
let foo = Foo<Bar<T>, Baz>()
let foo = SignalProducer<Signal<Value, Error>, Error>([ self.signal, next ]).flatten(.concat)
触发
let foo = 1↓+2
let foo = 1↓ + 2
let foo = 1↓ + 2
let foo = 1↓ + 2
let foo↓=1↓+2
let foo↓=1 + 2
let foo↓=bar
let range = 1↓ ..< 3
let foo = bar↓ ?? 0
let foo = bar↓??0
let foo = bar↓ != 0
let foo = bar↓ !== bar2
let v8 = Int8(1)↓ << 6
let v8 = 1↓ << (6)
let v8 = 1↓ << (6)
let foo = 1 > 2
Operator Function Whitespace
标识符 |
默认开启 |
支持自动更正 |
类别 |
分析仪 |
最低swift编译版本 |
operator_whitespace |
是 |
否 |
style |
否 |
3.0.0 |
自定义运算符的时候,前后需要用空格包围。
示例
非触发
func <| (lhs: Int, rhs: Int) -> Int {}
func <|< <A>(lhs: A, rhs: A) -> A {}
func abc(lhs: Int, rhs: Int) -> Int {}
触发
↓func <|(lhs: Int, rhs: Int) -> Int {}
↓func <|<<A>(lhs: A, rhs: A) -> A {}
↓func <| (lhs: Int, rhs: Int) -> Int {}
↓func <|< <A>(lhs: A, rhs: A) -> A {}
↓func <| (lhs: Int, rhs: Int) -> Int {}
↓func <|< <A>(lhs: A, rhs: A) -> A {}
Overridden methods call super
标识符 |
默认开启 |
支持自动更正 |
类别 |
分析仪 |
最低swift编译版本 |
overridden_super_call |
否 |
否 |
lint |
否 |
3.0.0 |
一些被覆写的方法应该总是调用父类
示例
非触发
class VC: UIViewController {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
}
}
class VC: UIViewController {
override func viewWillAppear(_ animated: Bool) {
self.method1()
super.viewWillAppear(animated)
self.method2()
}
}
class VC: UIViewController {
override func loadView() {
}
}
class Some {
func viewWillAppear(_ animated: Bool) {
}
}
class VC: UIViewController {
override func viewDidLoad() {
defer {
super.viewDidLoad()
}
}
}
触发
class VC: UIViewController {
override func viewWillAppear(_ animated: Bool) {↓
//Not calling to super
self.method()
}
}
class VC: UIViewController {
override func viewWillAppear(_ animated: Bool) {↓
super.viewWillAppear(animated)
//Other code
super.viewWillAppear(animated)
}
}
class VC: UIViewController {
override func didReceiveMemoryWarning() {↓
}
}
Override in Extension
标识符 |
默认开启 |
支持自动更正 |
类别 |
分析仪 |
最低swift编译版本 |
override_in_extension |
否 |
否 |
lint |
否 |
3.0.0 |
扩展中不应该覆写方法
示例
非触发
extension Person {
var age: Int { return 42 }
}
extension Person {
func celebrateBirthday() {}
}
class Employee: Person {
override func celebrateBirthday() {}
}
class Foo: NSObject {}
extension Foo {
override var description: String { return "" }
}
struct Foo {
class Bar: NSObject {}
}
extension Foo.Bar {
override var description: String { return "" }
}
触发
extension Person {
override ↓var age: Int { return 42 }
}
extension Person {
override ↓func celebrateBirthday() {}
}
Pattern Matching Keywords
标识符 |
默认开启 |
支持自动更正 |
类别 |
分析仪 |
最低swift编译版本 |
pattern_mactching_keywords |
否 |
否 |
idiomatic |
否 |
3.0.0 |
通过将关键字移出元组来进行模式匹配
示例
非触发
switch foo {
default: break
}
switch foo {
case 1: break
}
switch foo {
case bar: break
}
switch foo {
case let (x, y): break
}
switch foo {
case .foo(let x): break
}
switch foo {
case let .foo(x, y): break
}
switch foo {
case .foo(let x), .bar(let x): break
}
switch foo {
case .foo(let x, var y): break
}
switch foo {
case var (x, y): break
}
switch foo {
case .foo(var x): break
}
switch foo {
case var .foo(x, y): break
}
触发
switch foo {
case (↓let x, ↓let y): break
}
switch foo {
case .foo(↓let x, ↓let y): break
}
switch foo {
case (.yamlParsing(↓let x), .yamlParsing(↓let y)): break
}
switch foo {
case (↓var x, ↓var y): break
}
switch foo {
case .foo(↓var x, ↓var y): break
}
switch foo {
case (.yamlParsing(↓var x), .yamlParsing(↓var y)): break
}
Prefixed Top-Level Constant
标识符 |
默认开启 |
支持自动更正 |
类别 |
分析仪 |
最低swift编译版本 |
prefixed_toplevel_constant |
否 |
否 |
style |
否 |
3.0.0 |
顶级的常量需要加k作为前缀
示例
非触发
private let kFoo = 20.0
public let kFoo = false
internal let kFoo = "Foo"
let kFoo = true
struct Foo {
let bar = 20.0
}
private var foo = 20.0
public var foo = false
internal var foo = "Foo"
var foo = true
var foo = true, bar = true
var foo = true, let kFoo = true
let
kFoo = true
var foo: Int {
return a + b
}
let kFoo = {
return a + b
}()
触发
private let ↓Foo = 20.0
public let ↓Foo = false
internal let ↓Foo = "Foo"
let ↓Foo = true
let ↓foo = 2, ↓bar = true
var foo = true, let ↓Foo = true
let
↓foo = true
let ↓foo = {
return a + b
}()
Private Actions
标识符 |
默认开启 |
支持自动更正 |
类别 |
分析仪 |
最低swift编译版本 |
private_action |
否 |
否 |
lint |
否 |
3.0.0 |
IBAction 必须使用private修饰
示例
非触发
class Foo {
@IBAction private func barButtonTapped(_ sender: UIButton) {}
}
struct Foo {
@IBAction private func barButtonTapped(_ sender: UIButton) {}
}
class Foo {
@IBAction fileprivate func barButtonTapped(_ sender: UIButton) {}
}
struct Foo {
@IBAction fileprivate func barButtonTapped(_ sender: UIButton) {}
}
private extension Foo {
@IBAction func barButtonTapped(_ sender: UIButton) {}
}
fileprivate extension Foo {
@IBAction func barButtonTapped(_ sender: UIButton) {}
}
触发
class Foo {
@IBAction ↓func barButtonTapped(_ sender: UIButton) {}
}
struct Foo {
@IBAction ↓func barButtonTapped(_ sender: UIButton) {}
}
class Foo {
@IBAction public ↓func barButtonTapped(_ sender: UIButton) {}
}
struct Foo {
@IBAction public ↓func barButtonTapped(_ sender: UIButton) {}
}
class Foo {
@IBAction internal ↓func barButtonTapped(_ sender: UIButton) {}
}
struct Foo {
@IBAction internal ↓func barButtonTapped(_ sender: UIButton) {}
}
extension Foo {
@IBAction ↓func barButtonTapped(_ sender: UIButton) {}
}
extension Foo {
@IBAction public ↓func barButtonTapped(_ sender: UIButton) {}
}
extension Foo {
@IBAction internal ↓func barButtonTapped(_ sender: UIButton) {}
}
public extension Foo {
@IBAction ↓func barButtonTapped(_ sender: UIButton) {}
}
internal extension Foo {
@IBAction ↓func barButtonTapped(_ sender: UIButton) {}
}
Private Outlets
标识符 |
默认开启 |
支持自动更正 |
类别 |
分析仪 |
最低swift编译版本 |
private_outlet |
否 |
否 |
lint |
否 |
3.0.0 |
OBOutlets 必须是使用private修饰来保证对UIKit的高层不可见
示例
非触发
class Foo {
@IBOutlet private var label: UILabel?
}
class Foo {
@IBOutlet private var label: UILabel!
}
class Foo {
var notAnOutlet: UILabel
}
class Foo {
@IBOutlet weak private var label: UILabel?
}
class Foo {
@IBOutlet private weak var label: UILabel?
}
触发
class Foo {
@IBOutlet ↓var label: UILabel?
}
class Foo {
@IBOutlet ↓var label: UILabel!
}
补充
大部分场景下都比较讨厌storyboard、xib的方式,无他,习惯。
Private Over filePrivate
标识符 |
默认开启 |
支持自动更正 |
类别 |
分析仪 |
最低swift编译版本 |
private_over_fileprivate |
是 |
是 |
idiomatic |
否 |
3.0.0 |
首选使用private而不是fileprivate
示例
非触发
extension String {}
private extension String {}
public
enum MyEnum {}
open extension
String {}
internal extension String {}
extension String {
fileprivate func Something(){}
}
class MyClass {
fileprivate let myInt = 4
}
class MyClass {
fileprivate(set) var myInt = 4
}
struct Outter {
struct Inter {
fileprivate struct Inner {}
}
}
触发
↓fileprivate enum MyEnum {}
↓fileprivate class MyClass {
fileprivate(set) var myInt = 4
}
补充
swift4访问权限控制
Access Control
Private Unit Test
标识符 |
默认开启 |
支持自动更正 |
类别 |
分析仪 |
最低swift编译版本 |
private_unit_test |
是 |
否 |
lint |
否 |
3.0.0 |
默认跳过标记为private
的单元测试
示例
非触发
class FooTest: XCTestCase { func test1() {}
internal func test2() {}
public func test3() {}
}
internal class FooTest: XCTestCase { func test1() {}
internal func test2() {}
public func test3() {}
}
public class FooTest: XCTestCase { func test1() {}
internal func test2() {}
public func test3() {}
}
private class Foo: NSObject { func test1() {}
internal func test2() {}
public func test3() {}
}
private class Foo { func test1() {}
internal func test2() {}
public func test3() {}
}
public class FooTest: XCTestCase { func test1(param: Int) {}
}
触发
private ↓class FooTest: XCTestCase { func test1() {}
internal func test2() {}
public func test3() {}
private func test4() {}
}
class FooTest: XCTestCase { func test1() {}
internal func test2() {}
public func test3() {}
private ↓func test4() {}
}
internal class FooTest: XCTestCase { func test1() {}
internal func test2() {}
public func test3() {}
private ↓func test4() {}
}
public class FooTest: XCTestCase { func test1() {}
internal func test2() {}
public func test3() {}
private ↓func test4() {}
}
Prohibited Interface Builder
标识符 |
默认开启 |
支持自动更正 |
类别 |
分析仪 |
最低swift编译版本 |
prohibited_interface_builder |
否 |
否 |
lint |
否 |
3.0.0 |
避免使用Interface Builder
生成视图
示例
非触发
class ViewController: UIViewController {
var label: UILabel!
}
class ViewController: UIViewController {
@objc func buttonTapped(_ sender: UIButton) {}
}
触发
class ViewController: UIViewController {
@IBOutlet ↓var label: UILabel!
}
class ViewController: UIViewController {
@IBAction ↓func buttonTapped(_ sender: UIButton) {}
}
Prohibited calls to super
标识符 |
默认开启 |
支持自动更正 |
类别 |
分析仪 |
最低swift编译版本 |
prohibited_super_call |
否 |
否 |
lint |
否 |
3.0.0 |
有一些方法应该避免直接调用父类
示例
非触发
class VC: UIViewController {
override func loadView() {
}
}
class NSView {
func updateLayer() {
self.method1()
}
}
public class FileProviderExtension: NSFileProviderExtension {
override func providePlaceholder(at url: URL, completionHandler: @escaping (Error?) -> Void) {
guard let identifier = persistentIdentifierForItem(at: url) else {
completionHandler(NSFileProviderError(.noSuchItem))
return
}
}
}
触发
class VC: UIViewController {
override func loadView() {↓
super.loadView()
}
}
class VC: NSFileProviderExtension {
override func providePlaceholder(at url: URL, completionHandler: @escaping (Error?) -> Void) {↓
self.method1()
super.providePlaceholder(at:url, completionHandler: completionHandler)
}
}
class VC: NSView {
override func updateLayer() {↓
self.method1()
super.updateLayer()
self.method2()
}
}
class VC: NSView {
override func updateLayer() {↓
defer {
super.updateLayer()
}
}
}