我发现了一件有趣的事:
class A {
let name = "A"
deinit {
print(self.name)
print(self === Weak.value)
print(Weak.value?.name ?? "nil")
}
}
enum Weak {
static weak var value: A? = nil
}
var a = A()
Weak.value = a
a = A() //to call deinit
Run Code Online (Sandbox Code Playgroud)
输出是
A
false
nil
Run Code Online (Sandbox Code Playgroud)
因此,当一个对象执行其deinit方法时,它可以访问自己的属性.但是这个对象的另一个弱引用已经变为零,即使这个对象实际上还没有在此时被释放.
根据这篇文章,每个对象都有一个侧表.这是我的假设:当一个对象的deinit方法正在执行时,该对象尚未被释放.但是从该对象的side-table到此对象的指针已被删除(或标记为nil).所以没有人可以访问它除了它自己.这实际上是Swift 4的工作原理.
我说的是对的吗?这篇文章不是问题,只是想了解更多细节.如果有人可以解释更多,那就太好了.
Swift 4.2引入了一种新CaseIterable协议,可自动生成枚举中所有案例的数组属性.
现在我想实现Enum继承的默认方法CaseIterable,可以返回给定案例的下一个案例.如果这种情况是最后一种情况,请返回第一种情况.像一个圆圈.
如果我为特定的Enum写这个,它可以正常工作:
enum Direction: CaseIterable {
case east, south, west, north
func next() -> Direction {
let all = type(of: self).allCases // 1
if self == all.last! {
return all.first!
} else {
let index = all.firstIndex(of: self)!
return all[index + 1]
}
}
}
print(Direction.east.next()) // south
print(Direction.north.next()) // east
Run Code Online (Sandbox Code Playgroud)
但我想对许多Enum实现这个功能.重复复制和粘贴代码并不好(更不用说这个代码对于每个枚举都是完全相同的).
所以我尝试了这个.但出了点问题.
(我建议你将以下代码复制到游乐场,以便更快地理解这个问题):
extension CaseIterable {
func next() -> Self {
let all = type(of: self).allCases // 1
if self == all.last { …Run Code Online (Sandbox Code Playgroud)