2017-08-02 1 views
1

Je développe une application iOS. Pour mes demandes d'API serveur, j'utilise des méthodes wrapper Alamofire qui, entre autres paramètres, prennent des fermetures @escaping - généralement pour les indicateurs de succès, échec et gestion de chargement. Les fermetures elles-mêmes sont déclarées lazy var dans mes sous-classes ViewControllers. Un exemple d'une telle fermeture:Les fermetures d'échappement provoquent des erreurs de l'éditeur de liens dans la configuration de la version

lazy var sendRequestSuccess = {() -> Void in 
    // do something here 
} 

Comment j'appelle mes méthodes wrapper API:

APIRequestHelper.sharedInstance.sendRequest(success: requestSuccess, progress: animateActivityIndicator, failure: requestFailure) 
// APIRequestHelper is my class for all API requests 

Et mes méthodes de l'API dans le cas général ressemble à ceci:

func sendRequest(success: @escaping() -> Void, progress: @escaping (AnimationAction) -> Void, failure: @escaping (String?) -> Void) { 
// Alamofire request sending and response handling goes here 
} 

Ma question

Lorsque je compile mon application au Debug configuration, tout se construit et fonctionne bien. Cependant, dans la configuration Release tous mes @escaping fermetures (96 d'entre eux jusqu'à présent) générer des erreurs de l'éditeur de liens qui ressemble à ceci:

"__TFFC8<my app name>27AddressPickerViewControllerg23getPlaceLocationFailureFGSqSS_T_auL_4selfS0_", referenced from: 
     __TTSf4d___TFFC8<my app name>27AddressPickerViewControllerg23getPlaceLocationFailureFGSqSS_T_U_FGSqSS_T_ in AddressPickerViewController.o 
    "__TFFC8<my app name>26RequestsListViewControllerg22getRequestsListSuccessFGSqGSaCS_5Order__T_auL_4selfS0_", referenced from: 
     __TTSf4g___TFFC8<my app name>26RequestsListViewControllerg22getRequestsListSuccessFGSqGSaCS_5Order__T_U_FGSqGSaS1___T_ in RequestsListViewController.o 
    "__TFFC8<my app name>19LoginViewControllerg19getCountriesFailureFGSqSS_T_auL_4selfS0_", referenced from: 
     __TTSf4g___TFFC8<my app name>19LoginViewControllerg19getCountriesFailureFGSqSS_T_U_FGSqSS_T_ in LoginViewController.o 

avec quelques messages plus supplémentaires:

ld: symbol(s) not found for architecture arm64 
clang: error: linker command failed with exit code 1 (use -v to see invocation) 

Ce que j'ai essayé

En ce qui concerne quelques autres questions SO qui se réfèrent aux erreurs de l'éditeur de liens, je me suis assuré que j'ai $(inherited) dans mes «Autres indicateurs de liens» dans Paramètres de construction> Liaison. En fait, les options (bibliothèques listées) sont les mêmes pour les configurations Debug et Release. J'ai également essayé d'activer et de désactiver «Build Active Architecture Only» dans Build Settings> Architectures. Cependant, la plupart de ces questions sont liées à diverses bibliothèques tierces alors que dans mon cas, les fermetures, qui font partie du langage lui-même, semblent causer des problèmes.

Ceci est le premier problème dans ma carrière de développeur qui m'a amené à écrire ma propre question SO si gros merci d'avance.

Répondre

0

Je devais trouver la solution moi-même, donc je l'écrirai ici au cas où quelqu'un aurait le même problème.

Il s'avère que le problème était dans ma syntaxe de fermeture @escaping. Je n'ai pas fourni la liste de capture et l'éditeur de liens a eu des problèmes, peut-être en raison d'une possibilité de cycle de rétention. Aussi puisque je vais utiliser un weak self dans les fermetures, je vais maintenant utiliser le chaînage optionnel pour tous les appels au self.

donc je suis passé par toutes mes fermetures et ont changé leur syntaxe de

lazy var someOperationSuccess = {(someStringParameter: String?, someIntParameter: Int?) -> Void in 
      print ("Success") 
      self.doSomething() 
     } 

à

lazy var someOperationSuccess: (String?, Int?) -> Void = {[weak self] someStringParameter, someIntParameter in 
     print ("Success") 
     self?.doSomething() 
    }