2016-09-17 7 views
2

В моем Swift кода (в Framework), я выражаю UIColor для поддержки умножения и сложения операторов, как это:Почему я получаю эту ошибку с автогенерированными заголовками фреймов в Swift?

public protocol Interpolatable { 
    static func * (lhs: Self, rhs: Double) -> Self 
    static func + (lhs: Self, rhs: Self) -> Self 
} 
extension UIColor: Interpolatable { 
    public static func *(lhs: UIColor, rhs: Double) -> Self { 
     var r = CGFloat(0), g = CGFloat(0), b = CGFloat(0), a = CGFloat(0) 
     let t = CGFloat(rhs) 
     lhs.getRed(&r, green: &g, blue: &b, alpha: &a) 
     return self.init(red: r * t, green: g * t, blue: b * t, alpha: a * t) 
    } 
    public static func +(lhs: UIColor, rhs: UIColor) -> Self { 
     var lhsR = CGFloat(0), lhsG = CGFloat(0), lhsB = CGFloat(0), lhsA = CGFloat(0) 
     var rhsR = CGFloat(0), rhsG = CGFloat(0), rhsB = CGFloat(0), rhsA = CGFloat(0) 
     lhs.getRed(&lhsR, green: &lhsG, blue: &lhsB, alpha: &lhsA) 
     rhs.getRed(&rhsR, green: &rhsG, blue: &rhsB, alpha: &rhsA) 
     return self.init(red: lhsR + rhsR, green: lhsG + rhsG, blue: lhsB + rhsB, alpha: lhsA + rhsA) 
    } 
} 

Который работает отлично, как ожидается, в детской площадке или в отдельном проекте, но когда Я положил его в Framework, компилятор генерирует этот код в рамочном заголовке MyFramework-Swift.h:

@interface UIColor (SWIFT_EXTENSION(Animation)) 
+ (nonnull instancetype)*:(UIColor * _Nonnull)lhs :(double)rhs; 
+ (nonnull instancetype)+:(UIColor * _Nonnull)lhs :(UIColor * _Nonnull)rhs; 
@end 

И этот сгенерированный код выдает эту ошибку:

error: expected selector for Objective-C method 
+ (nonnull instancetype)*:(UIColor * _Nonnull)lhs :(double)rhs; 
         ^

(с той же ошибкой для оператора +)

Я думаю, что это используется только для доступа рамки из Objective-C, потому что если я просто удалить содержимое этого заголовка файла мой проект строит и работает правильно.

Является ли это морщиной в Xcode или Swift toolchain, или мне не хватает чего-то, что я должен делать при перегрузке таких операторов? Обратите внимание, что меня интересует то, что пытается сделать компилятор, и почему это проблема, а не просто короткий ответ на обходной путь или его исправление.

+0

Странно. Я не думаю, что он должен включать в себя пользовательских операторов в объективной зоне C вообще ... – nhgrif

ответ

3

В конечном итоге я понял, что происходит, и исправил его.

Что происходит:

При создании рамки, он должен быть разоблачен как модуля, так что она может использоваться другими частями кода. Многие классы библиотек (включая UIColor) на самом деле являются классами Objective-C, которые можно использовать из Swift, поэтому при их расширении по умолчанию ваши расширения также доступны в Objective-C. Компилятор генерирует заголовки Objective-C для вашей структуры, объявляя ваши расширения как методы Objective-C, и в этом случае * и + являются недопустимыми именами методов в Objective-C, поэтому он вызывает ошибку компиляции.

Решение:

Чтобы сообщить компилятору, что вы не хотите, чтобы эти методы были доступны из Objective-C, добавьте @nonobjc перед объявлением метода.

@nonobjc public static func *(lhs: UIColor, rhs: Double) -> Self { 
...} 
@nonobjc public static func +(lhs: UIColor, rhs: UIColor) -> Self { 
...}