/ / Perché @noescape non viene applicato automaticamente alle chiusure Swift quando è necessario? - Ios, rapido, chiusure

Perché @noescape non viene applicato automaticamente alle chiusure Swift quando è necessario? - Ios, rapido, chiusure

Mi chiedo perché il tag noescape non viene rilevato automaticamente e deve essere esplicitamente applicato.

Infatti, è in qualche modo rilevato in fase di compilazione, perché provare ad aggiungere il tag @noescape a una funzione con chiusure di escape comporta un errore.

Quindi la domanda è perché ... perché? noescape deve essere aggiunto esplicitamente e Apple non l'ha creato per essere aggiunto automaticamente quando è necessario?

risposte:

2 per risposta № 1

Modificare: Swift 3 apporta alcune modifiche qui:

  • Le chiusure che non sfuggono sono quelle predefinite. Ora non devi fare domanda @noescape alle dichiarazioni delle funzioni che prendono le chiusure come parametri se si desidera richiedere chiusure che non sfuggano. (Invece, devi applicare @escaping nei casi in cui tu fare pianifica di memorizzare una chiusura dopo il ritorno della tua funzione.)
  • La "fuga" di una chiusura ora fa parte della dichiarazione del tipo di funzione. Quindi, invece di un parametro che sembra @escaping completionHandler: (Bool, Error) -> Void, suo completionHandler: @escaping (Bool, Error) -> Void.

È abbastanza difficile riscrivere la mia intera risposta per riflettere questo, quindi lo lascio qui per ora ... continua a leggere per whys dietro la fuga, basta ricordare di invertire le dichiarazioni di fuga / fuga. :) O leggere Chiusure di fuga nella versione Swift 3 di The Swift Programming Language.


@noescape non è solo un suggerimento per le ottimizzazioni del compilatore, ma fa parte dell'interfaccia che una dichiarazione di funzione presenta ai chiamanti. Se viene dichiarato un parametro per una funzione @noescape o consente di chiudere le chiusure cambia il modo in cui un chiamante di quella funzione scrive la chiusura che passano come parametro.

Ad esempio, data la funzione (da SequenceType):

func filter(@noescape includeElement: (Self.Generator.Element) throws -> Bool) rethrows -> [Self.Generator.Element]

Se volessi filtrare una raccolta in base a determinati criteri che richiedono la chiamata di un metodo self, So di poterlo fare tranquillamente senza preoccuparmi se la chiusura verrà catturata self e creare un ciclo di conservazione.

// horribly contrived example
class Foo {
var things: [Thing]
func isCurrentlyAwesomeThing(thing: Thing) -> Bool { /*...*/ }
func thingsThatAreAwesomeRightNow() -> [Thing] {
return things.filter {
return isCurrentlyAwesomeThing($0)
}
}
}

Se filter permesso una chiusura di fuga, la chiusura che chiama isCurrentlyAwesomeThing() catturerebbe self. (E quindi richiede che quel metodo sia chiamato con un esplicito self. prefisso.) E se l'implementazione di filter effettivamente salvato la chiusura oltre il tempo di esecuzione di quella funzione, non ci sarebbe una perdita di memoria perché la chiusura mantiene self e self conserva l'array di cui filter la funzione ha ricevuto la chiusura.

Quando si chiama una funzione i cui parametri di chiusura non vengono dichiarati @noescape, devi rendere conto di questa possibilità. Questo è il motivo per cui vedi le chiamate che aggiungono a [weak self] lista di cattura e una forte redeclaration all'interno della chiusura per essere sicuri self non viene deallocato durante la chiusura (o almeno un [unowned self] nei casi in cui si è ragionevolmente certi che la chiusura non duri più a lungo di self.)

Se i parametri di chiusura non fossero decorati come @noescape (o come non fugare attraverso l'assenza di quel decoratore), non si dovrebbe sapere quando si chiama una funzione che richiede una chiusura, se si deve fare attenzione a ciò che cattura questa chiusura.


0 per risposta № 2

Se utilizzi un qualsiasi parametro di funzione come notescape che non puoi memorizzare in un'altra chiusura, non puoi usare dispatch_asynch e non puoi chiamare la chiusura non-noescape dalla chiusura di noescape

Lo scopo dell'attributo noescape con cui dovrebbe essere in quella chiusura