2017-09-15 1 views
10

[Swift]Gestionnaire d'échappement et de complétion Swift @

Bonjour, J'essaie de mieux comprendre la 'fermeture' de Swift.

Mais @escaping et Completion Handler sont trop difficiles à comprendre

Je cherchai de nombreux messages et documents officiels de Swift, mais je me sentais Stil pas assez

Ceci est l'exemple de code des documents officiels

var completionHandlers: [()->Void] = [] 

func someFunctionWithEscapingClosure(completionHandler: @escaping()->Void){ 
    completionHandlers.append(completionHandler) 
} 
func someFunctionWithNoneescapingClosure(closure:()->Void){ 
    closure() 
} 

class SomeClass{ 
    var x:Int = 10 
    func doSomething(){ 
     someFunctionWithEscapingClosure { 
      self.x = 100 
      //not excute yet 
     } 
     someFunctionWithNoneescapingClosure { 
      x = 200 
     } 
    } 
} 
let instance = SomeClass() 
instance.doSomething() 
print(instance.x) 

completionHandlers.first?() 
print(instance.x) 

J'ai entendu qu'il y a deux façons et raisons d'utiliser @esacping

Premières s fermeture Toring, le second est Async objectif d'exploitation

Et, à partir de maintenant ils sont mes questions

Tout d'abord, si doSomething puis en exécutant someFunctionWithEscapingClosure va exécuter avec le paramètre de fermeture et que la fermeture sera enregistrée dans le tableau variable globale.

Je pense que la fermeture est {100} = self.x

Comment self dans {self.x = 100} qui a sauvé dans la variable globale completionHandlers peut se connecter à instance cet objet de SomeClass? Deuxièmement, je comprends someFunctionWithEscapingClosure comme ceci.

Pour stocker la fermeture de variable locale completionHandler à la variable globale 'completionHandlers` nous utilisons le mot clé @escaping!

sans @escaping mot-clé someFunctionWithEscapingClosure rendement, variable locale completionHandler enlèvera de la mémoire

@escaping est de garder cette fermeture dans la mémoire

Est-ce exact?

Enfin, je m'interroge sur l'existence de cette grammaire.

Peut-être que cela est une question très rudimentaire

si nous voulons une exécution de la fonction après une fonction spécifique

pourquoi ne pas nous suffit d'appeler une fonction après appel de fonction spécifique

ce sont les différences entre l'utilisation de modèle ci-dessus et en utilisant la fonction de rappel d'échappement

merci de lire de longues questions et désolé pour je ne suis pas natif

Répondre

14

D'abord, je veux dire « Très bonne question :) »

achèvement Handler:

On suppose que l'utilisateur est mise à jour d'une application lors de son utilisation.Vous voulez certainement informer l'utilisateur quand c'est fait. Vous pouvez éventuellement faire apparaître une boîte qui dit, "Félicitations, maintenant, vous pouvez profiter pleinement!"

Alors, comment exécuter un bloc de code seulement après le téléchargement a été terminé? En outre, comment animer certains objets seulement après qu'un contrôleur de vue a été déplacé à l'autre? Eh bien, nous allons découvrir comment en concevoir un comme un patron. Sur la base de ma liste de vocabulaire vaste, les gestionnaires d'achèvement pour se tiennent

Do stuff when things have been done

Pour plus de détails, veuillez visiter this blog post.

Ce lien me donne une clarté complète sur les gestionnaires d'achèvement (du point de vue du développeur, il définit exactement ce que nous devons comprendre).

fermetures @escaping:

Lorsque vous passez la fermeture dans les arguments d'une fonction, à l'aide après le corps de la fonction est exécuté et retourne le compilateur en arrière. Lorsque la fonction se termine, l'étendue de la fermeture passée existe et a une existence en mémoire, jusqu'à ce que la fermeture soit exécutée.

Il y a plusieurs façons de échapper à la fermeture en fonction contenant:

  • Stockage: Lorsque vous avez besoin de stocker la fermeture dans la variable globale, la propriété ou tout autre stockage qui existe dans le passé mémoire du La fonction d'appel est exécutée et renvoie le compilateur. Exécution asynchrone: Lorsque vous exécutez la fermeture de manière asynchrone dans la file d'attente d'expédition, la file d'attente conservera la fermeture en mémoire pour vous et pourra être utilisée à l'avenir. Dans ce cas, vous n'avez aucune idée quand la fermeture sera exécutée.

Lorsque vous essayez d'utiliser la fermeture dans ces scénarios, le compilateur Swift affiche l'erreur:

error screenshot

Pour plus de clarté sur ce sujet, vous pouvez consulter this post on Medium.

J'espère que vous obtiendrez une bonne compréhension de ce lien.

Si vous avez encore des questions (mais soyez sûr de lire ce lien ligne par ligne d'abord, c'est très bien expliqué) alors n'hésitez pas à partager votre commentaire.

Merci

+0

vos liens ont été très utiles –

+0

Merci, profitez de codage à Swift –