2015-09-19 4 views
6

Cercando di caricare codice HTML da un servizio Web in una WebView, ottengo questo errore:Il riferimento alla proprietà in chiusura richiede un "sé" esplicito. per rendere la semantica di cattura esplicite

Reference to property 'webviewHTML' in closure requires explicit 'self.' to make capture semantics explicit

Che cosa significa, e come posso caricare la stringa HTML nel mio vista web?

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(); 
} 

risposta

6

Prima di rispondere a questa domanda è necessario sapere cos'è un ciclo di memoria. Vedere Resolving Strong Reference Cycles Between Class Instances From Apple's documenation


Ora che sapete che cosa un ciclo di memoria è:

Tale errore è compilatore Swift si dice

"Hey the NSURLSession closure is trying to keep webviewHTML in the heap and therefor self ==> creating a memory cycle and I don't think Mr.Clark wants that here. Imagine if we make a request which takes forever and then the user navigates away from this page. It won't leave the heap.I'm only telling you this, yet you Mr.Clark must create a weak reference to the self and use that in the closure."

Per ulteriori informazioni vedere this moment naturalmente Stanford.

Codice

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(); 
} 

corretta Per i dettagli in profondità, vedere questo Shall we always use [unowned self] inside closure in Swift

+1

Ottima risposta e grazie - questo ha più senso ora. – ThisClark

8

Uso di self è un riconoscimento esplicito riferimento (noto anche come cattura) un costrutto (classe/struct/enum) in una chiusura, implicando che self non sarà rilascia finché detta chiusura è deallocato.

Quando si pensa a questo proposito, self avrebbe potuto benissimo stato dedotto, (come è, quando si utilizza webviewHTML fuori una chiusura), ma è un intenzionale progettazione decisione di non inferire, come Swift è un prima lingua di sicurezza.

+0

Forse, ma questo abbassa il livello di astrazione e riduce la regolarità nella lingua. Inoltre, è solo più sicuro perché viene utilizzato il conteggio dei riferimenti. –

Problemi correlati