Подтвердить что ты не робот

Быстрое расширение: одна и та же функция расширения в двух модулях

Скажем, у меня есть Framework под названием SwiftKit, который имеет метод класса расширения UIView с именем someClassMethod и свойство с именем someProperty внутри него:

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

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

И у меня также есть Framework под названием SwiftFoundation, который также имеет метод класса расширения UIView с именем someClassMethod и свойство с именем someProperty внутри него:

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

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

Затем я создал проект, внедряющий эти Framework, все, если я импортирую оба из них в один и тот же быстрый файл и получаю доступ к этим расширениям, я получил "Неоднозначное использование ошибки 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 из Swift Foundation

someClassMethod из Swift Foundation

Мой вопрос: как я могу назвать эти расширения (как метод класса/экземпляра, свойства) без двусмысленного? Если я не могу, значит ли это, что мы должны добавлять префикс к именам расширений, как обычно, с Objective-C?

4b9b3361

Ответ 1

подробности

  • Swift 3, Xcode 8.1
  • Swift 4, Xcode 9.1

проблема

Фреймворки SwiftFoundation и SwiftKit имеют одинаковые имена свойств и функций

решение

Way1

Используйте разные имена свойств и функций

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

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

Way2

Сгруппируйте свойства и функции

// 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. Посмотрите на изображение ниже, вы можете увидеть класс SwiftKit и swiftFoundationSomeClassMethod() внутри SwiftFoundation. Это может запутать других разработчиков.

enter image description here

Ответ 2

Если это расширение объекта ObjC NSObject, например UIView, тогда да, метод расширения требует префикса.

Однако те, кто считает подчеркивание неприглядным, могут попробовать эту альтернативу, использующую протоколы Swift, чтобы заменить UIColor.red.my_toImage() на UIColor.red.my.toImage() здесь: Лучший способ управлять быстрыми расширениями в вашем проекте