swift 扩展 : same extension function in two Modules

标签 swift namespaces swift-extensions

假设我有一个名为 SwiftKit 的框架,它有一个名为 someClassMethod 的 UIView 扩展类方法和一个名为 someProperty 的属性:

// SwiftKit
public extension UIView {
    class func someClassMethod() {
        print("someClassMethod from Swift Kit")
    }
    
    var someProperty: Double {
        print("someProperty from Swift Kit")
        return 0
    }
}

我还有一个名为 SwiftFoundation 的框架,它还有一个名为 someClassMethod 的 UIView 扩展类方法和一个名为 someProperty 的属性:

// SwiftFoundation
public extension UIView {
    class func someClassMethod() {
        print("someClassMethod from Swift Foundation")
    }
    
    var someProperty: Double {
        print("someProperty from Swift Foundation")
        return 0
    }
}

然后我创建了一个引入这些框架的项目,事情是,如果我在同一个 swift 文件中导入它们并访问这些扩展,我会得到一个“模糊使用 someProperty/someClassMethod()”错误,即使我指定以 SwiftKit.UIView.someClassMethod() 的形式调用:

import UIKit
import SwiftKit
import SwiftFoundation

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        self.view.someProperty              // error: Ambiguous use of 'somProperty'
        SwiftKit.UIView.someClassMethod()   // error: Ambiguous use of 'someClassMethod()'
    }
}

如果我只导入其中一个,模棱两可的错误就会消失,但会发生一件奇怪的事情:

import UIKit
import SwiftKit
//import SwiftFoundation

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        self.view.someProperty
        SwiftKit.UIView.someClassMethod()
    }
}

控制台打印出:

someProperty from Swift Foundation

someClassMethod from Swift Foundation

我的问题是:我怎样才能明确地调用这些扩展(类/实例方法、属性)?如果不能,是否意味着我们应该像通常使用 Objective-C 那样为扩展名称添加前缀?

最佳答案

详情

  • swift 3、Xcode 8.1
  • swift 4、Xcode 9.1
  • swift 5.1,Xcode 11.2.1

问题

frameworks SwiftFoundation 和SwiftKit 具有相同名称的属性和函数

决定

方式1

使用不同的属性和函数名称

// SwiftFoundation
public extension UIView {
    public class func swiftFoundationSomeClassMethod() {
        print("someClassMethod from Swift Foundation")
    }

    public var swiftFoundationSomeProperty: Double {
        print("someProperty from Swift Foundation")
        return 0
    }
}

方式2

对属性和函数进行分组

// SwiftKit
public extension UIView {
    public class SwiftKit {
        public class func someClassMethod() {
            print("someClassMethod from Swift Kit")
        }

        public var someProperty: Double {
            print("someProperty from Swift Kit")
            return 0
        }
    }

    var SwiftKit: SwiftKit { return SwiftKit() }
}

结果

import UIKit
import SwiftKit
import SwiftFoundation

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        _ = view.SwiftKit.someProperty
        UIView.SwiftKit.someClassMethod()

        _ = view.swiftFoundationSomeProperty
        UIView.swiftFoundationSomeClassMethod()
    }
}

项目

enter image description here enter image description here

你的方法

SwiftFoundation.UIView.swiftFoundationSomeClassMethod()

您使用命名空间的变体是不正确的,因为来自两个框架的所有 UIView 扩展都包含在您的 UIView 类中。看下面的图片,你可以在 SwiftFoundation 中看到 SwiftKit 类和 swiftFoundationSomeClassMethod() 。这可能会使其他开发人员感到困惑。

enter image description here

关于 swift 扩展 : same extension function in two Modules,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32736698/

相关文章:

Swift 结构扩展函数 - "Cannot assign to ' origin' in 'self' "

swift - NSData to Type 转换为错误的枚举

objective-c - 使用 CGSize Points 或 Pixels 确定 UIFont 大小

c# - 命名空间和类型问题

namespaces - 支柱 2 : root namespace acting same as default namespace

swift - 扩展的静态函数的派生类型

ios - 表格 View 单元格偏移

ios - 执行 String.Encoding.utf16 和 String.Encoding。 utf16BigEndian 意味着同样的事情即 UTF16BigEndian?

swift - 两个不同模块中的相同类扩展

swift - 无法在 swift 上扩展扩展添加的结构