Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save inamiy/1094dd8701d627f9392e44c0145a41bd to your computer and use it in GitHub Desktop.
Save inamiy/1094dd8701d627f9392e44c0145a41bd to your computer and use it in GitHub Desktop.
Swift instance-method retain cycle behavior
import Foundation
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
class A: NSObject {
let name: String
var callback: (() -> ())?
func funcDo() {}
let letDo: () -> () = {}
// NOTE: Only available if subclass of `NSObject`
let letDoUsingSelf: () -> () = {
print(self)
}
init(_ name: String) {
self.name = name
print("`\(name)` is created")
}
deinit {
print("=== `\(name)` deinit ===")
}
}
// Wrap with async for non-global reference
DispatchQueue.main.async {
// funcDo
print("----------------------------------------")
print("funcDo")
do {
// Optional + indirect closure
do {
var a: A? = A("a1")
a?.callback = {
a?.funcDo()
}
a = nil // deinited
}
// Optional + direct
do {
var a: A? = A("a2")
a?.callback = a?.funcDo
a = nil // NOT DEINITED
}
// Non-Optional + indirect closure
do {
let a: A = A("a3")
a.callback = {
a.funcDo()
}
// NOT DEINITED
}
// Non-Optional + direct call
do {
let a: A = A("a4")
a.callback = a.funcDo
// NOT DEINITED
}
}
// letDo
print("----------------------------------------")
print("letDo")
do {
// Optional + indirect closure
do {
var a: A? = A("a1")
a?.callback = {
a?.letDo()
}
a = nil // deinited
}
// Optional + direct
do {
var a: A? = A("a2")
a?.callback = a?.letDo
a = nil // deinited
}
// Non-Optional + indirect closure
do {
let a: A = A("a3")
a.callback = {
a.letDo()
}
// NOT DEINITED
}
// Non-Optional + direct call
do {
let a: A = A("a4")
a.callback = a.letDo
// deinited
}
}
// letDoUsingSelf
print("----------------------------------------")
print("letDoUsingSelf")
do {
// Optional + indirect closure
do {
var a: A? = A("a1")
a?.callback = {
a?.letDoUsingSelf()
}
a = nil // deinited
}
// Optional + direct
do {
var a: A? = A("a2")
a?.callback = a?.letDoUsingSelf
a = nil // deinited
}
// Non-Optional + indirect closure
do {
let a: A = A("a3")
a.callback = {
a.letDoUsingSelf()
}
// NOT DEINITED
}
// Non-Optional + direct call
do {
let a: A = A("a4")
a.callback = a.letDoUsingSelf
// deinited
}
}
DispatchQueue.main.async {
print("done")
}
}
@inamiy
Copy link
Author

inamiy commented Jun 15, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment