2017-10-13 9 views
0

J'ai une méthode avec une fermeture en tant que paramètre qui est par défaut une fonction «fictive» si aucune fermeture n'est fournie. Cependant, chaque fois que j'essayer d'omettre le paramètre avec la valeur par défaut, le compilateur génère l'erreur:Pourquoi ne puis-je pas ignorer un paramètre de fermeture avec une fonction par défaut dans Swift?

Missing argument for parameter 'closureFuncWithDefault' in call
Insert 'parameterClosureFuncWithDefault: <#(object) -> Void#>'

Mon code est le suivant:

func functionWithDefault (object: SCNReferenceNode = SCNReferenceNode(), 
       closureWithDefault: @escaping (_ object: SCNReferenceNode)->Void = { _ in return }) { 

    otherClassInstance.loadObject (object, loadedHandler: { [unowned self] loadedObject in DispatchQueue.main.async { 

      self.otherMethod (loadedObject) 
      closureWithDefault (virtualObject) 
     } 
    }) 

} 

Puis d'ailleurs:

// some code 

var objectThing = SCNReferenceNode (URL: .....) 

// 
// code block... 
// 

functionWithDefault (object: objectThing) // <-- This throws the error. 

Classe SCN et de telles choses ne sont pas les choses pertinentes, plutôt, la bonne façon d'avoir un paramètre de fermeture avec un défaut et être capable de l'utiliser.

+0

Fonctionne bien pour moi. Pouvez-vous essayer de nettoyer votre projet et de le reconstruire? – nathan

+0

Non lié, je ne suggérerais pas d'utiliser 'unowned' quand on appelle quelque chose de façon asynchrone sur un autre thread. Vous n'avez aucune garantie que 'self' existe encore lorsque l'autre exécution exécute la fermeture. Utilisez 'faible '. – Rob

Répondre

0

La syntaxe commune est d'utiliser une fermeture en option, en l'appelant avec ?:

func functionWithDefault (object: SCNReferenceNode = SCNReferenceNode(), closure: @escaping ((_ object: SCNReferenceNode) -> Void)? = nil) { 
    otherClassInstance.loadObject (object) { [unowned self] loadedObject in 
     DispatchQueue.main.async { 
      self.otherMethod (loadedObject) 
      closure?(virtualObject) 
     } 
    } 
} 

Ou, considérant un exemple plus simple:

func foo(completion: @escaping ((Bool) -> Void)? = nil) { 
    performAsynchronousTask { success in 
     completion?(success) 
    } 
} 

Et vous pouvez appeler cela comme soit:

foo() 

ou

foo { success in 
    if success { ... } else { ... } 
}