If a property marked with the lazy modifier is accessed by multiple threads simultaneously and the property has not yet been initialized, there’s no guarantee that the property will be initialized only once.
Lazy 不是线程安全的!
struct A {
lazy var a: Int = {
return Int.random(in: 0 ... 1000)
}()
}
var a = A()
for _ in 0 ..< 100 {
DispatchQueue.global().async {
print(a.a)
}
}
// print
952
119
756
248
997
Unlike stored instance properties, you must always give stored type properties a default value. This is because the type itself does not have an initializer that can assign a value to a stored type property at initialization time.
Stored type properties are lazily initialized on their first access. They are guaranteed to be initialized only once, even when accessed by multiple threads simultaneously, and they do not need to be marked with the lazy modifier.
- 类型属性是线程安全的, 并且是 Lazy 的. 如下打印.
- 可以用 class 来替换 static, 它不能以
=
的方式初始化, 必须提供具体的实现,
否则会报错, 提示使用static
来代替, class 标记的类型属性, 是可以被子类型重写的, 这是主要的区别, 值类型(struct, enum) 等是没法使用 class 标记的类型属性, 没有继承.
class Temp {}
class A {
static var p1 = "???"
static var p2: String {
return "?????"
}
class var p3: String {
return "??????"
}
}
class AA: A {
override init() {
super.init()
print("A init")
}
override class var p3: String {
return "p3 ??????"
}
class var p4: Temp {
return Temp()
}
static var p5 = Temp()
}
struct B {
static let a = 10
static let aa = AA()
init() {
print("B init")
}
}
_ = B()
B.aa
B.aa
// print
B init
A init
网友评论