在捕获它之前我是否必须打开一个可选项?

时间:2018-02-23 09:14:53

标签: swift

说我有这个班:

class ExpirableClosure {

    let closure: () -> Void
    let isExpired: () -> Bool

    func execute() {

        guard !isExpired() else { return }
        closure()
    }

    init(_ closure: @escaping () -> Void, _ isExpired: @escaping () -> Bool) {

        self.closure = closure; self.isExpired = isExpired
    }
}

然后用这种方法保存闭包:

var savedClosures = [ExpirableClosure]()
func saveClosure(_ closure: @escaping () -> Void, expireWith object: AnyObject? = nil) {

    let isExpired = (object != nil) ? { [weak object] in object == nil } : { false }
    savedClosures.append(ExpirableClosure(closure, isExpired))
}

在解包之前捕获可选项会导致ExpirableClosure立即过期,因为当函数终止时,对可选项的唯一强引用会被销毁吗?

更新

如果您运行此代码:

class Object {}
var handle: Object? = Object()
saveClosure({}, expireWith: handle)
print(savedClosures.first!.isExpired()) // prints false
handle = nil
print(savedClosures.first!.isExpired()) // prints true

this online compiler上你得到那些印刷文件。那么快速解开幕后的可选项并轻微地引用其价值?  为什么isExpired会返回false,或者在将handle设置为nil后返回true?

1 个答案:

答案 0 :(得分:0)

你的“handle”变量只有对象的强引用,直到它被设置为nil。此时,对象中的{[weak object]中的可选“object”变量== nil}变为nil,因为它是弱引用,条件返回true。

如果您没有对过期对象的其他强引用,则该条目将立即过期:

// for example
saveClosure({}, expireWith: Object())
print(savedClosures.first!.isExpired()) // would print true