A reference to a property in closure requires an explicit self. make obvious capture semantics

Trying to load HTML from web service into web view, I get this error:

A reference to the webviewHTML property in the closure requires an explicit self. to make capture semantics explicit

What does this mean and how can I load an HTML string into my webview?

func post(url: String, params: String) { let url = NSURL(string: url) let params = String(params); let request = NSMutableURLRequest(URL: url!); request.HTTPMethod = "POST" request.HTTPBody = params.dataUsingEncoding(NSUTF8StringEncoding) let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in if error != nil { print("error=\(error)") return } var responseString : NSString!; responseString = NSString(data: data!, encoding: NSUTF8StringEncoding) webviewHTML.loadHTMLString(String(responseString), baseURL: nil) } task.resume(); } 
+6
swift swift2
source share
2 answers

Before answering this question, you should know what a memory cycle is. See Resolving strong reference loops between class instances from Apple documenation


Now that you know what a memory loop is:

This error is a Swift compiler telling you

“Hey, closing the NSURLSession is trying to keep the webviewHTML in a bunch and therefore self ==> creating a memory loop, and I don’t think that Mr. Clark wants here. Imagine if we make a request that accepts forever and then the user goes from this pages. It won’t leave a bunch. I’m telling you this, but you, Mr. Clark, must create a weak link to yourself and use it in closing.

For more information, see this point in the Stanford course.

Correct code

 func post(url: String, params: String) { let url = NSURL(string: url) let params = String(params); let request = NSMutableURLRequest(URL: url!); request.HTTPMethod = "POST" request.HTTPBody = params.dataUsingEncoding(NSUTF8StringEncoding) weak var weakSelf = self // ADD THIS LINE AS WELL let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in if error != nil { print("error=\(error)") return } var responseString : NSString!; responseString = NSString(data: data!, encoding: NSUTF8StringEncoding) weakSelf.webviewHTML.loadHTMLString(String(responseString), baseURL: nil) // REFER to webviewHTML using weakSelf!!!!!! } task.resume(); } 

See details in . We will always use [unowned self] inside closure in Swift .

+6
source share

The use of self is an explicit confirmation of the reference (also known as capture ) of the construct (class / struct / enum) in the closure, implying that self will not be released until the specified closure is released.

When you think about it, self can be very well deduced (like this when you use webviewHTML outside of closure), but it is an intentional design decision not to do this, since Swift is a safe first language .

+8
source share

All Articles