Skip to content

Instantly share code, notes, and snippets.

@ChrisMarshallNY
Last active April 13, 2020 13:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ChrisMarshallNY/6cd0101e4b4855efd00a0b394a9d0a0d to your computer and use it in GitHub Desktop.
Save ChrisMarshallNY/6cd0101e4b4855efd00a0b394a9d0a0d to your computer and use it in GitHub Desktop.
Companion Playground to the Closures, Contexts and Capture Post (Part 2)
var externalContextVariable: Int = 5
// These are errors
//let closure = {[inout externalContextVariable] () -> Void in
//let closure = {[var externalContextVariable] () -> Void in
let closure = {[externalContextVariable] () -> Void in
// This is an error.
// externalContextVariable = 6
print("externalContextVariable is \(externalContextVariable)")
}
closure()
let closure2 = {
externalContextVariable = 6
print("externalContextVariable is \(externalContextVariable)")
}
closure2()
class SomeClass {
var myString: String = ""
var myInt: Int = 0
func spewOutAClosure(intValue: Int, stringValue: String) -> () -> Void {
self.myString = stringValue
self.myInt = intValue
return {print("externalContextVariable is \(externalContextVariable)\nself.myInt is \(self.myInt)\nself.someString is \"\(self.myString)\"")}
}
}
externalContextVariable = 10
var oneInstanceOfSomeClass: SomeClass! = SomeClass()
var oneInstanceOfAClassBoundClosure: () -> Void = oneInstanceOfSomeClass.spewOutAClosure(intValue: 1000, stringValue: "One Thousand")
oneInstanceOfAClassBoundClosure()
oneInstanceOfSomeClass.myInt = 20
oneInstanceOfSomeClass.myString = "Twenty"
oneInstanceOfAClassBoundClosure()
class SomeClassWeakOverride: SomeClass {
override func spewOutAClosure(intValue: Int, stringValue: String) -> () -> Void {
self.myString = stringValue
self.myInt = intValue
return {[weak self] in
if nil != self {
print("externalContextVariable is \(externalContextVariable)\nself.myInt is \(self!.myInt)\nself.someString is \"\(self!.myString)\"")
} else {
print("self is nil!")
}
}
}
}
class SomeClassUnownedOverride: SomeClass {
override func spewOutAClosure(intValue: Int, stringValue: String) -> () -> Void {
self.myString = stringValue
self.myInt = intValue
return {[unowned self] in print("externalContextVariable is \(externalContextVariable)\nself.myInt is \(self.myInt)\nself.someString is \"\(self.myString)\"")}
}
}
var oneWeakInstanceOfSomeClass: SomeClassWeakOverride! = SomeClassWeakOverride()
oneInstanceOfAClassBoundClosure = oneWeakInstanceOfSomeClass.spewOutAClosure(intValue: 900, stringValue: "Nine Hundred")
oneInstanceOfAClassBoundClosure()
oneInstanceOfSomeClass = SomeClass()
oneInstanceOfAClassBoundClosure = oneInstanceOfSomeClass.spewOutAClosure(intValue: 10, stringValue: "Ten")
oneInstanceOfAClassBoundClosure()
oneInstanceOfSomeClass.myInt = 15
oneInstanceOfSomeClass.myString = "Fifteen"
oneInstanceOfSomeClass = nil
oneInstanceOfAClassBoundClosure()
print("\n")
var anotherInstanceOfSomeClass: SomeClassWeakOverride! = SomeClassWeakOverride()
var anotherInstanceOfAClassBoundClosure = anotherInstanceOfSomeClass.spewOutAClosure(intValue: 10, stringValue: "Ten")
anotherInstanceOfAClassBoundClosure()
anotherInstanceOfSomeClass.myInt = 15
anotherInstanceOfSomeClass.myString = "Fifteen"
anotherInstanceOfAClassBoundClosure()
anotherInstanceOfSomeClass = nil
anotherInstanceOfAClassBoundClosure()
print("\n")
var contextCheck: String = "Declaration"
// This is the declaration phase of the closure. It is declared, but not instantiated.
func generateAClosureForMe() -> () -> String {
return {[contextCheck] in return contextCheck}
}
contextCheck = "Instantiation"
// This is the instantiation phase. We ask the factory function to give us an instance of the closure.
let myClosure = generateAClosureForMe()
contextCheck = "Execution"
// This is the execution phase. We run the closure here.
print("The state was captured during the " + myClosure() + " phase.")
contextCheck = "Declaration"
// This is the declaration phase of the closure. It is declared, but not instantiated.
func generateAClosureForMe2() -> () -> String {
return {return contextCheck}
}
contextCheck = "Instantiation"
// This is the instantiation phase. We ask the factory function to give us an instance of the closure.
let myClosure2 = generateAClosureForMe2()
contextCheck = "Execution"
// This is the execution phase. We run the closure here.
print("The state was captured during the " + myClosure2() + " phase.")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment