【问题标题】:Can a Swift framework reference another Swift framework's class extensions?一个 Swift 框架可以引用另一个 Swift 框架的类扩展吗?
【发布时间】:2017-01-04 08:30:28
【问题描述】:

当我在一个 Swift 框架中尝试调用在另一个 Swift 框架中定义为 UIView 扩展的函数时,我收到“无法识别的选择器发送到实例”错误。它看起来非常类似于通过将 -ObjC 标志传递给链接器 (https://developer.apple.com/library/ios/qa/qa1490/_index.html) 解决的问题以及在框架中扩展泛型时发生的问题 (Swift Framework does not include symbols from extensions to generic structs)。不幸的是,我的问题似乎有所不同,因为:

  1. 定义扩展的框架和定义扩展的框架 正在尝试使用它是用 Swift 编写的。
  2. 这两个框架都是“Cocoa Touch 框架”,而不是静态库。
  3. 被扩展的类是 UIView,不是泛型的。
  4. 将 -ObjC 或 -all_load 添加到所有 涉及的目标没有解决问题。

上下文是我已向 iOS 项目添加了一个框架目标来容纳 IBDesignable 类。主项目的名称是“Vital”,框架的名称是“VitalDesignables”。我添加了另一个名为“VitalKit”的框架来存放 Vital 和 VitalDesignables 都依赖的代码。 VitalKit 定义此函数以从 nib 加载视图,VitalDesignables 中的一个类尝试在 init(frame: CGRect) 中调用它,当我在情节提要中引用它时,IB 无法加载该类。

public extension UIView {
    public func loadViewFromNib(nibName: String) -> UIView {
        let bundle = NSBundle(forClass: self.dynamicType)
        let nib = UINib(nibName: nibName, bundle: bundle)
        let topLevelItems = nib.instantiateWithOwner(self, options: nil)
        let topLevelViews = topLevelItems.filter() { $0.isKindOfClass(UIView) }
        precondition(topLevelViews.count == 1,
                     "There must be only one top-level view")

        return topLevelViews.first as! UIView
    }
}

【问题讨论】:

  • 从未尝试过,但如果你不能,那就太奇怪了。您必须将框架导入到您的框架中

标签: ios swift linker


【解决方案1】:

一定要在不包含扩展的框架中导入包含扩展的框架:

框架2:

public extension UIView {
    public func loadViewFromNib(nibName: String) -> UIView {
        let bundle = NSBundle(forClass: self.dynamicType)
        let nib = UINib(nibName: nibName, bundle: bundle)
        let topLevelItems = nib.instantiateWithOwner(self, options: nil)
        let topLevelViews = topLevelItems.filter() { $0.isKindOfClass(UIView) }
        precondition(topLevelViews.count == 1,
                     "There must be only one top-level view")

        return topLevelViews.first as! UIView
    }
}

框架1:

import Framework2

class ViewController : UIViewController
{
     override func viewDidLoad() {
        super.viewDidLoad()

        self.view!.loadViewFromNib("mynib")
    }
}

请记住,扩展程序必须是公开的。 (编辑:现在设置为open),我相信默认设置为内部,所以这意味着它可以在当前模块中看到,但外部模块将无法看到。

【讨论】:

    【解决方案2】:

    你不能随框架一起发布框架,所以如果 Framework2 参考 Framework1 可以用于编译目的。

    确保应用程序的 iOS 目标包含 Framework1 和 Framework1 都是嵌入式二进制文件,否则无法编译.. 见截图。

    【讨论】:

      猜你喜欢
      • 2016-05-04
      • 1970-01-01
      • 2011-03-31
      • 1970-01-01
      • 2013-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多