Swift: Weak referenced stored & nested blocks / closures - swift

I'm looking to nest a block / closure whilst another process completes off of the main thread like so
typealias FirstBlock = (jsonDictionary:NSDictionary?,errorCode:NSString?) -> Void
typealias SecondBlock = (complete:Bool?,errorCode:NSString?,dictionary:NSDictionary?) -> Void
Controller
func startPoint {
SomeNetworkManager.sharedInstance.firstProcess(self.someDictionary) { (complete, errorCode, dictionary) -> Void in
// I want to get here with a strong reference to these objects in this class only
print(complete,errorCode,dictionary)
}
}
SomeNetworkManager
func firstProcess(dictionary:NSDictionary?, completion:SecondBlock?) {
let request = HTTPRequest.init(requestWithPath:"path", httpMethod: .post) { (jsonDictionary, errorCode) -> Void in
let organisedDictionary:NSMutableDictionary = NSMutableDictionary()
// Some processing of the json into a new dictionary
dispatch_async(dispatch_get_main_queue()) {
if errorCode == nil {
completion!(complete:true,errorCode:nil,dictionary:organisedDictionary)
}
else {
completion!(complete:false,errorCode:errorCode,dictionary:nil)
}
}
}
request.postDataDictionary = refinementsDictionary as! NSMutableDictionary
request.request()
}
HTTPRequest
var processBlock:FirstBlock?
init(requestWithPath path:NSString, httpMethod method:HTTPMethod, andProcessBlock block:FirstBlock) {
super.init()
self.requestURL = NSURL(string:path as String);
self.responseData = NSMutableData()
self.processBlock = block
switch (method) {
case .post:
self.httpMethod = kPost
break;
case .put:
self.httpMethod = kPut
break;
default:
self.httpMethod = kGet
break;
}
}
// An NSURLConnection goes off, completes, I serialise the json and then...
func completeWithJSONDictionary(jsonDictionary:NSDictionary) {
self.processBlock!(jsonDictionary:jsonDictionary,errorCode:nil)
self.processBlock = nil
}
I'm missing something fundamental regarding ARC retain cycles because every time one of these is called I'm getting a memory leak.. I've had a look at
https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html
with no joy.. I think Defining a Capture List is the right area, but as for storing a block and how to define it I have no idea what I'm doing wrong.

In all likelihood, you're getting retain cycles because the completion block references the HttpRequest (probably via the calling object), references the completion block, something like:
class HttpReference {
let completion : ()->()
init(completion:()->()) {
self.completion = completion
}
}
class Owner {
var httpReference : HttpReference?
func someFunction() {
httpReference = HttpReference() {
print(self.httpReference)
}
}
}
There are two ways to break the cycle, either by using an unowned reference or a by using a weak reference, both are fairly similar, in this case, the norm would be to use an unowned reference to self by changing:
func someFunction() {
httpReference = HttpReference() { [unowned self] in
print(self.httpReference)
}
}
Now, self isn't retained, thus breaking the retain cycle.

Related

How do you aggregate data from DispatchQueue.concurrentPerform() using GCD?

How is one supposed to aggregate data when using Grand Central Dispatch's ConcurrentPerform()?
I am doing what is in the code below, but resultDictionary seems to lose all its data when the notify() block ends. Thus all I get is an empty dictionary that is returned from the function.
I am not sure why this is happening, because when I print or set a breakpoint I can see there is something in the resultDictionary before the block ends.
let getCVPDispatchQueue = DispatchQueue(label: "blarg",
qos: .userInitiated,
attributes: .concurrent)
let getCVPDispatchGroup = DispatchGroup()
var resultDictionary = dataIDToSRLParticleDictionary()
getCVPDispatchQueue.async { [weak self] in
guard let self = self else { return }
DispatchQueue.concurrentPerform(iterations: self.dataArray.count) { [weak self] (index) in
guard let self = self else { return }
let data = self.dataArray[index]
getCVPDispatchGroup.enter()
let theResult = data.runPartcleFilterForClosestParticleAndMaybeStopAudio()
switch theResult {
case .success(let CVParticle):
// If there was a CVP found, add it to the set.
if let theCVParticle = CVParticle {
self.dataIDsToCVPDictionary.addTodataIDToCVPDict(key: data.ID,
value: theCVParticle)
}
case .failure(let error):
os_log(.error, log: self.logger, "rundatasProcessing error: %s", error.localizedDescription)
self._isActive = false
}
getCVPDispatchGroup.leave()
}
getCVPDispatchGroup.notify(queue: .main) { [weak self] in
guard let self = self else { return }
print("DONE with \(self.dataIDsToCVPDictionary.getDictionary.count)")
resultDictionary = self.dataIDsToCVPDictionary.getDictionary
print("resultDictionary has \(self.dataIDsToCVPDictionary.getDictionary.count)")
}
}
print("Before Return with \(resultDictionary.count)")
return resultDictionary
}
Not sure if this will help, but this is simple class I made to made accessing the dictionary thread safe.
class DATASynchronizedIDToParticleDictionary {
var unsafeDictionary: DATAIDToDATAParticleDictionary = DATAIDToDATAParticleDictionary()
let accessQueue = DispatchQueue(label: "blarg2",
qos: .userInitiated,
attributes: .concurrent)
var getDictionary: DATAIDToDATAParticleDictionary {
get {
var dictionaryCopy: DATAIDToDATAParticleDictionary!
accessQueue.sync {
dictionaryCopy = unsafeDictionary
}
return dictionaryCopy
}
}
func addToDATAIDToCVPDict(key: String, value: DATAParticle) {
accessQueue.async(flags: .barrier) { [weak self] in
guard let self = self else { return }
self.unsafeDictionary[key] = value
}
}
func clearDictionary() {
accessQueue.async(flags: .barrier) { [weak self] in
guard let self = self else { return }
self.unsafeDictionary.removeAll()
}
}
}
You said:
I am doing what is in the code below, but resultDictionary seems to lose all its data when the notify() block ends. Thus all I get is an empty dictionary that is returned from the function.
The issue is that you’re trying to return a value that is calculated asynchronously. You likely want to shift to a completion block pattern.
As an aside, the dispatch group is not necessary. Somewhat ironically, the concurrentPerform is synchronous (i.e. it doesn’t proceed until the parallelized for loop is finished). So there’s no point in using notify if you know that you won’t get to the line after the concurrentPerform until all the iterations are done.
I’d also discourage having the concurrentPerform loop update properties. It exposes you to a variety of problems. E.g. what if the main thread was interacting with that object at the same time? Sure, you can synchronize your access, but it may be incomplete. It’s probably safer to have it update local variables only, and have the caller do the property update in its completion handler block. Obviously, you can go ahead and update properties (esp if you want to update your UI to reflect the in-flight progress), but it adds an additional wrinkle to the code that might not be necessary. Below, I’ve assumed it wasn’t necessary.
Also, while I appreciate the intent behind all of these [weak self] references, they’re really not needed, especially in your synchronization class DATASynchronizedIDToParticleDictionary. We often use weak references to avoid strong reference cycles. But if you don’t have strong references, they just add overhead unless you have some other compelling need.
OK, so let’s dive into the code.
First, I’d retire the specialized DATASynchronizedIDToParticleDictionary with a general-purpose generic:
class SynchronizedDictionary<Key: Hashable, Value> {
private var _dictionary: [Key: Value]
private let queue = DispatchQueue(label: Bundle.main.bundleIdentifier! + ".dictionary", qos: .userInitiated, attributes: .concurrent)
init(_ dictionary: [Key: Value] = [:]) {
_dictionary = dictionary
}
var dictionary: [Key: Value] {
queue.sync { _dictionary }
}
subscript(key: Key) -> Value? {
get { queue.sync { _dictionary[key] } }
set { queue.async(flags: .barrier) { self._dictionary[key] = newValue } }
}
func removeAll() {
queue.async(flags: .barrier) {
self._dictionary.removeAll()
}
}
}
Note, I’ve removed the unnecessary weak references. I’ve also renamed addToDATAIDToCVPDict and clearDictionary with a more natural subscript operator and a removeAll method that more closely mirrors the interface of the underlying Dictionary type. It results in more natural looking code. (And because this is a generic, we can use it for any dictionary that needs this sort of low level synchronization.)
Anyway, you can now declare a synchronized rendition of the dictionary like so:
let particles = SynchronizedDictionary(dataIDToSRLParticleDictionary())
And when I want to update the dictionary with some value, you can do:
particles[data.ID] = theCVParticle
And when I want retrieve actual underlying, wrapped dictionary, I can do:
let finalResult = particles.dictionary
While we’re at it, since we might want to keep track of an array of errors that needs to be synchronized, I might add an array equivalent type:
class SynchronizedArray<Value> {
private var _array: [Value]
private let queue = DispatchQueue(label: Bundle.main.bundleIdentifier! + ".array", qos: .userInitiated, attributes: .concurrent)
init(_ dictionary: [Value] = []) {
_array = dictionary
}
var array: [Value] {
queue.sync { _array }
}
subscript(index: Int) -> Value {
get { queue.sync { _array[index] } }
set { queue.async(flags: .barrier) { self._array[index] = newValue } }
}
func append(_ value: Value) {
queue.async(flags: .barrier) {
self._array.append(value)
}
}
func removeAll() {
queue.async(flags: .barrier) {
self._array.removeAll()
}
}
}
We can now turn our attention to the main routine. So rather than returning a value, we’ll instead give it an #escaping completion handler. And, as discussed above, we’d retire the unnecessary dispatch group:
func calculateAllClosestParticles(completion: #escaping ([String: CVParticle], [Error]) -> Void) {
let queue = DispatchQueue(label: "blarg", qos: .userInitiated, attributes: .concurrent)
let particles = SynchronizedDictionary(dataIDToSRLParticleDictionary())
let errors = SynchronizedArray<Error>()
queue.async {
DispatchQueue.concurrentPerform(iterations: self.dataArray.count) { index in
let data = self.dataArray[index]
let result = data.runPartcleFilterForClosestParticleAndMaybeStopAudio()
switch result {
case .success(let cvParticle):
// If there was a CVP found, add it to the set.
if let cvParticle = cvParticle {
particles[data.ID] = cvParticle
}
case .failure(let error):
errors.append(error)
}
}
DispatchQueue.main.async {
completion(particles.dictionary, errors.array)
}
}
}
Now, I don’t know what the right types were for the dictionary, so you might need to adjust the parameters of the completion. And you didn’t provide the rest of the routines, so I may have some details wrong here. But don’t get lost in the details, but just note the scrupulous avoidance of properties within the concurrentPerform and the passing of the results back in the completion handler.
You’d call it like so:
calculateAllClosestParticles { dictionary, errors in
guard errors.isEmpty else { return }
// you can access the dictionary and updating the model and UI here
self.someProperty = dictionary
self.tableView.reloadData()
}
// but don't try to access the dictionary here, because the asynchronous code hasn't finished yet
//
FWIW, while I used the reader-writer pattern you did in your example, in my experience, NSLock is actually more performant for quick synchronizations, especially when you are using concurrentPerform that might tie up all of the cores on your CPU, e.g.
class SynchronizedDictionary<Key: Hashable, Value> {
private var _dictionary: [Key: Value]
private let lock = NSLock()
init(_ dictionary: [Key: Value] = [:]) {
_dictionary = dictionary
}
var dictionary: [Key: Value] {
lock.synchronized { _dictionary }
}
subscript(key: Key) -> Value? {
get { lock.synchronized { _dictionary[key] } }
set { lock.synchronized { _dictionary[key] = newValue } }
}
func removeAll() {
lock.synchronized {
_dictionary.removeAll()
}
}
}
Where
extension NSLocking {
func synchronized<T>(_ closure: () throws -> T) rethrows -> T {
lock()
defer { unlock() }
return try closure()
}
}
Bottom line, you don’t want to force context switches for synchronization if you don’t have to.
When doing concurrent perform, if you have many dataPoints and if the time required by each call to runPartcleFilterForClosestParticleAndMaybeStopAudio is modest, you might want to consider “striding”, doing several datapoint in each iteration. It’s beyond the scope of this question, but just a FYI.
Not exactly sure what I did, but I moved the
resultDictionary = self.dataIDsToCVPDictionary.getDictionary
outside the first async block and that seem to allowed the data to be retained/remain for the function return.

Save struct in background mutating function

I'm trying to save a struct in background but I get this error :
closure cannot implicitly capture a mutating self parameter
This is my code :
//MARK: Parse self methods
fileprivate mutating func ParseSave(_ completionBlock: #escaping SuccessCompletionBlock) {
let message: PFObject = PFObject(className: "Message")
if let id = self.id {
//this object exit just update it
message.objectId = id
}
// set attributes
if let text = self.text {
message["text"] = text
}
message["sender"] = PFUser(withoutDataWithObjectId: self.sender.id)
message["conversation"] = PFObject(withoutDataWithClassName: "Conversation", objectId: conversationId)
message["viewed"] = self.viewed
message.saveInBackground { (success, error) in
if success {
// the next 3 lines cause the error : (when I try to update the struct - self )
self.id = message.objectId
self.createdAt = message.createdAt ?? self.createdAt
self.updatedAt = message.updatedAt ?? self.updatedAt
}
completionBlock(success, error)
}
}
I've checked those question: 1 - 2 I've added the #escaping
but didn't work.
I think it will help if we minimally elicit the error message you're getting. (For delay, see dispatch_after - GCD in swift?.)
struct S {
var name = ""
mutating func test() {
delay(1) {
self.name = "Matt" // Error: Closure cannot ...
// ... implicitly capture a mutating self parameter
}
}
}
The reason lies in the peculiar nature of struct (and enum) mutation: namely, it doesn't really exist. When you set a property of a struct, what you're really doing is copying the struct instance and replacing it with another. That is why only a var-referenced struct instance can be mutated: the reference must be replaceable in order for the instance to be mutable.
Now we can see what's wrong with our code. Obviously it is legal for a mutating method to mutate self; that is what mutating means. But in this case we are offering to go away for a while and then suddenly reappear on the scene (after 1 second, in this case) and now mutate self. So we are going to maintain a copy of self until some disconnected moment in the future, when self will suddenly be somehow replaced. That is incoherent, not least because who knows how the original self may have been mutated in the meantime, rendering our copy imperfect; and the compiler prevents it.
The same issue does not arise with a nonescaping closure:
func f(_ f:()->()) {}
struct S {
var name = ""
mutating func test() {
f {
self.name = "Matt" // fine
}
}
}
That's because the closure is nonescaping; it is executed now, so the incoherency about what will happen in the future is absent. This is an important difference between escaping and nonescaping closures, and is one of the reasons why they are differentiated.
Also, the same issue does not arise with a class:
class C {
var name = ""
func test() {
delay(1) {
self.name = "Matt" // fine
}
}
}
That's because the class instance is captured by reference in the closure, and a class instance is mutable in place.
(See also my little essay here: https://stackoverflow.com/a/27366050/341994.)

Unowned self in a closure in a closure

If I have a closure in another closure is it enough to use unowned/weak once in the outer closure to avoid retain cycles?
Example:
foo.aClosure({[unowned self] (allowed: Bool) in
if allowed {
self.doStuff()
self.something.anotherClosure({ (s:String) -> (Void) in
self.doSomethingElse(s)
})
}
})
Only declaring weak or unowned self in the capture list of the outer closure is enough to avoid retain cycles if you don't create a strong reference to self within the outer closure (e.g. by doing: guard let strongSelf = self else { return }).
If you do create a strong reference within the closure, you must add a capture list to the inner closure to ensure that it captures your strong reference to self weakly.
Here are some examples:
import Foundation
import PlaygroundSupport
class SomeObject {
typealias OptionalOuterClosure = ((Int) -> Void)?
typealias InnerClosure = () -> Void
var outerClosure: OptionalOuterClosure
func setup() {
// Here are several examples of the outer closure that you can easily switch out below
// All of these outer closures contain inner closures that need references to self
// optionalChecks
// - has a capture list in the outer closure
// - uses the safe navigation operator (?) to ensure that self isn't nil
// this closure does NOT retain self, so you should not see the #2 calls below
let optionalChecks: OptionalOuterClosure = { [weak self] callNumber in
print("outerClosure \(callNumber)")
self?.delayCaller { [weak self] in
print("innerClosure \(callNumber)")
self?.doSomething(callNumber: callNumber)
}
}
// copiedSelfWithInnerCaptureList
// - has a capture list in the outer closure
// - creates a copy of self in the outer closure called strongSelf to ensure that self isn't nil
// - has a capture list in the inner closure
// - uses the safe navigation operator (?) to ensure strongSelf isn't nil
// this closure does NOT retain self, so you should not see the #2 calls below
let copiedSelfWithInnerCaptureList: OptionalOuterClosure = { [weak self] callNumber in
guard let strongSelf = self else { return }
print("outerClosure \(callNumber)")
strongSelf.delayCaller { [weak strongSelf] in
print("innerClosure \(callNumber)")
strongSelf?.doSomething(callNumber: callNumber)
}
}
// copiedSelfWithoutInnerCaptureList
// - has a capture list in the outer closure
// - creates a copy of self in the outer closure called strongSelf to ensure that self isn't nil
// - does NOT have a capture list in the inner closure and does NOT use safe navigation operator
// this closure DOES retain self, so you should see the doSomething #2 call below
let copiedSelfWithoutInnerCaptureList: OptionalOuterClosure = { [weak self] callNumber in
guard let strongSelf = self else { return }
print("outerClosure \(callNumber)")
strongSelf.delayCaller {
print("innerClosure \(callNumber)")
strongSelf.doSomething(callNumber: callNumber)
}
}
// retainingOuterClosure
// - does NOT have any capture lists
// this closure DOES retain self, so you should see the doSomething #2 call below
let retainingOuterClosure: OptionalOuterClosure = { callNumber in
print("outerClosure \(callNumber)")
self.delayCaller {
print("innerClosure \(callNumber)")
self.doSomething(callNumber: callNumber)
}
}
// Modify which outerClosure you would like to test here
outerClosure = copiedSelfWithInnerCaptureList
}
func doSomething(callNumber: Int) {
print("doSomething \(callNumber)")
}
func delayCaller(closure: #escaping InnerClosure) {
delay(seconds: 1, closure: closure)
}
deinit {
print("deinit")
}
}
// Handy delay method copied from: http://alisoftware.github.io/swift/closures/2016/07/25/closure-capture-1/
func delay(seconds: Int, closure: #escaping () -> Void) {
let time = DispatchTime.now() + .seconds(seconds)
DispatchQueue.main.asyncAfter(deadline: time) {
print("🕑")
closure()
}
}
var someObject: SomeObject? = SomeObject()
someObject?.setup()
// Keep a reference to the outer closure so we can later test if it retained someObject
let copiedOuterClosure = someObject!.outerClosure!
// Call the outer closure once just to make sure it works
copiedOuterClosure(1)
// Wait a second before we destroy someObject to give the first call a chance to work
delay(seconds: 1) {
// Run the outerClosure again to check if we retained someObject
copiedOuterClosure(2)
// Get rid of our reference to someObject before the inner closure runs
print("de-referencing someObject")
someObject = nil
}
// Keep the main run loop going so our async task can complete (need this due to how playgrounds work)
PlaygroundPage.current.needsIndefiniteExecution = true
Yes, however I would use weak over unowned because self.doStuff() with throw an exception if nil while if you use weak and its self?.doStuff() there won't be an exception thrown and it just won't execute.
You can test this in the playground with the following code:
typealias Closure = () -> Void
class ClosureObject {
var closure:Closure?
func saveClosure(closure:Closure?) {
self.closure = closure
}
}
let mainClosureObject = ClosureObject()
class TestObject {
let closureObject = ClosureObject()
func log() {
print("logged")
}
func run() {
mainClosureObject.saveClosure() {[weak self] in
self?.closureObject.saveClosure() {
self?.log()
}
}
}
}
var testObject:TestObject? = TestObject()
let closureObject = testObject?.closureObject
testObject?.run()
mainClosureObject.closure?()
closureObject?.closure?()
testObject = nil
closureObject?.closure?()
mainClosureObject.closure?()
closureObject?.closure?()
and compare it with:
typealias Closure = () -> Void
class ClosureObject {
var closure:Closure?
func saveClosure(closure:Closure?) {
self.closure = closure
}
}
let mainClosureObject = ClosureObject()
class TestObject {
let closureObject = ClosureObject()
func log() {
print("logged")
}
func run() {
mainClosureObject.saveClosure() {
self.closureObject.saveClosure() {
self.log()
}
}
}
}
var testObject:TestObject? = TestObject()
let closureObject = testObject?.closureObject
testObject?.run()
mainClosureObject.closure?()
closureObject?.closure?()
testObject = nil
closureObject?.closure?()
mainClosureObject.closure?()
closureObject?.closure?()

Issue with Swift Closures

I'm having an issue retrieving data from within an closure. I'm calling function called getWallImages which is supposed to return an array. I can print the contents of the array from within the closure, but outside of it the array is empty.
import Foundation
import Parse
class WallPostQuery {
var result = [WallPost]()
func getWallImages() -> [WallPost] {
let query = WallPost.query()!
query.findObjectsInBackgroundWithBlock { objects, error in
if error == nil {
if let objects = objects as? [WallPost] {
self.result = objects
//This line will print the three PFObjects I have
println(self.result)
}
}
}
//this line prints [] ...empty array?
println(result)
return self.result
}
}
Question
How do I get values out of a closure?
That is because println(result) is executed BEFORE self.results = objects. The closure is executed asynchronously so it executes afterwards. Try making a function that uses results which can be called form the closure:
var result = [WallPost]()
func getWallImages() {
let query = WallPost.query()!
query.findObjectsInBackgroundWithBlock { objects, error in
if error == nil {
if let objects = objects as? [WallPost] {
self.result = objects
//This line will print the three PFObjects I have
println(self.result)
self.useResults(self.result)
}
}
}
}
func useResults(wallPosts: [WallPost]) {
println(wallPosts)
}
}
Another solution to your problem, so that you can return it from that function is to create your own closure:
var result = [WallPost]()
func getWallImages(completion: (wallPosts: [WallPost]?) -> ()) {
let query = WallPost.query()!
query.findObjectsInBackgroundWithBlock { objects, error in
if error == nil {
if let objects = objects as? [WallPost] {
self.result = objects
//This line will print the three PFObjects I have
println(self.result)
completion(wallPosts: self.result)
} else {
completion(wallPosts: nil)
}
} else {
completion(wallPosts: nil)
}
}
}
func useResults(wallPosts: [WallPost]) {
println(wallPosts)
}
}
What is happening is that the method is returning before the closure executes.
Fundamentally, you're running into a problem with they way you are managing asynchronous callbacks.
Asynchronous vs synchronous execution, what does it really mean?
You need to create a way of notifying your caller from within your closure. You can achieve this by: requiring your own closure as an input parameters; using a delegate pattern; using a notification.
https://codereview.stackexchange.com/questions/87016/swift-ios-call-back-functions
Each has their benefits/drawbacks, and it depends on your particular situation. The simplest way to get started with async data fetches, is to pass in your own closure. From there, you can jump to another pattern such as the delegate pattern if the need arises.
I think the latter of println(result) is called before because findObjectsInBackgroundWithBlock is executed on background as its name suggests.
So, you can confirm result in the following way,
import Foundation
import Parse
class WallPostQuery {
var result = [WallPost]() {
didSet {
println(result)
}
}
func getWallImages() {
let query = WallPost.query()!
query.findObjectsInBackgroundWithBlock { objects, error in
if error == nil {
if let objects = objects as? [WallPost] {
self.result = objects
//This line will print the three PFObjects I have
println(self.result)
}
}
}
}
}

Strong reference cycle for closures in Swift

I was going through the documentation (chapter on “Automatic Reference Counting” section “Strong Reference Cycles for Closures”) and I can't seem to figure out cases, when defining a class, in which I should keep a strong reference to self (the instance of that class) in a closure to a property.
Capture Lists seem always the best solution to avoid memory leaks, and I really can't think of any scenarios in which I should keep a strong reference cycle.
Here are the examples that the documentation gives:
class HTMLElement {
let name: String
let text: String?
// Without Capture List
#lazy var asHTML: () -> String = {
if let text = self.text {
return "<\(self.name)>\(text)</\(self.name)>"
} else {
return "<\(self.name) />"
}
}
init(name: String, text: String? = nil) {
self.name = name
self.text = text
}
deinit {
println("\(name) is being deinitialized")
}
}
class HTMLElement {
let name: String
let text: String?
// With Capture List
#lazy var asHTML: () -> String = {
[unowned self] in
if let text = self.text {
return "<\(self.name)>\(text)</\(self.name)>"
} else {
return "<\(self.name) />"
}
}
init(name: String, text: String? = nil) {
self.name = name
self.text = text
}
deinit {
println("\(name) is being deinitialized")
}
}
You need to keep a strong reference to self if you’re creating a closure to be executed by an object or function whose lifetime may not match self’s.
For example:
class A {
func do() {
dispatch_async(dispatch_get_global_queue(0, 0)) {
println("I printed \(self) some time in the future.")
}
}
}
var a : A? = A()
a.do()
a = nil // <<<
At the arrow the main function body will release its last reference to the newly created instance of A, but the dispatch queue needs to keep a hold on it until the closure is done executing.