Chapter 23: Async Closures and Memory Management

大綱

Playgrounds and reference cycles

Playgrounds sometimes add extra "invisible" references to objects as you run them. Because of this, objects do not deallocate when then normally should. This makes it difficult to study reference counting using Playgrounds. Because of this, for this chapter you can use a Swift macOS command line tool to test out reference cycles.

Reference cycles for classes

Weak references

  • Weak references不會增加某個object的reference count。

  • Weak只能用在宣告成optional的那些屬性上。

  • 在上面的例子中,不是每個tutorial都一定有editor, 因此把它宣告成weak。

Unowned references

  • 跟Weak一樣,不會增加reference count, 但只能用在那些不是optional的屬性上。

  • 例如,每個tutorial都一定會有個author。

Reference cycles for closures

  • Clousure也是屬於一個reference type,所以也有可能跟其他type產生reference cycle。

  • 在Tutorial class中加入一個lazy property

    • lazy property不會被assign任何值,直到第一次使用。

Capture lists

  • A capture list is a list of variables captured by a closure.

  • A capture list appears at the very beginning of the closure before any arguments.

  • With reference types, a capture list will cause the closure to capture and store the current reference stored inside the captured variable.

Unowned self

  • 在closure的capture list加上unowned 解除closure跟物件tutorial之間的reference cycle。

Handling escaping closures

  • non-escaping: Array中的flitter closure

    • After the filter completes, the closure is never accessed again and is said to be non-escaping

  • escaping closures: GCD closure

    • The danger is that since the order of completion changes from run to run, you must be careful not to access an unowned reference that may have disappeared

GCD

Weak self

  • you declared self as unowned. However, this code isn’t safe! If, for some reason, the editor went out of scope before editTutorial had completed, self.feedback would crash when it eventually executed.

The strong-weak pattern

Key points

  • Use a weak reference to break a strong reference cycle if a reference may become nil at some point in its lifecycle.

  • Use an unowned reference to break a strong reference cycle when you know a reference always has a value and will never be nil.

  • You must use self inside a closure’s body. This is the way the Swift compiler hints to you that you need to be careful not to make a circular reference.

  • Capture lists define how you capture values and references in closures.

  • The strong weak pattern extends an object’s lifecycle for asynchronous closures.

  • An escaping closure can be used after the corresponding function returns.

Last updated