【问题标题】:Escaping closures give linker errors in Release configuration转义闭包会导致发布配置中的链接器错误
【发布时间】:2017-08-02 09:33:52
【问题描述】:

我正在开发一个 iOS 应用程序。

对于我的服务器 API 请求,我使用 Alamofire 包装器方法,除其他参数外,还采用 @escaping 闭包——通常用于成功、失败和处理加载指标。闭包本身在我的 ViewControllers 子类中被声明为lazy vars。这种关闭的一个例子:

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

我如何调用我的 API 包装方法:

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

一般情况下,我的 API 方法如下所示:

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

我的问题

当我在Debug 配置中构建我的应用程序时,一切都可以顺利构建和运行。然而,在Release 配置中,我所有的@escaping 闭包(目前有96 个)都会生成如下所示的链接器错误:

"__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

还有一些附加信息:

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

我尝试了什么

根据其他一些涉及链接器错误的 SO 问题,我确保在“构建设置”>“链接”的“其他链接器标志”中有 $(inherited)。事实上,DebugRelease 配置的选项(列出的库)是相同的。我还尝试在“构建设置”>“架构”中打开和关闭“仅构建活动架构”。 但是,大多数此类问题都与各种第三方库有关,而就我而言,@escaping 闭包是语言本身的一部分,似乎会造成麻烦。

这是我开发人员职业生涯中的第一个问题,它让我写出了自己的 SO 问题,非常感谢。

【问题讨论】:

    标签: ios swift linker closures


    【解决方案1】:

    我必须自己找到解决方案,所以我会在这里写下来,以防万一有人遇到同样的问题。

    原来问题出在我的@escaping 闭包语法中。我没有提供捕获列表,链接器有问题,可能是由于保留周期的可能性。此外,由于我将在闭包中使用weak self,因此我现在必须对所有对self 的调用使用可选链接。

    所以我检查了我所有的闭包并改变了它们的语法

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-10-27
      • 2012-08-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-07
      相关资源
      最近更新 更多