2

我正在尝试在 NSLayoutAnchor 上创建一个扩展方法来接受乘数。我得到一个奇怪的 Swift 编译错误(Swift 3,XCode 8.2.1),不是在扩展文件中,而是在模块的相应 .h 文件(该文件由编译器自动生成)中:

@interface NSLayoutAnchor (SWIFT_EXTENSION(MYMODULENAME))
- (NSLayoutConstraint * _Nonnull)constraintTo:(NSLayoutAnchor</* AnchorType */> * _Nonnull)anchor multiplier:(CGFloat)m;
@end

错误指向/* AnchorType */并说:“预期类型”。嗯,这是有道理的,因为/* AnchorType */它不是类型而是注释。但是我AnchorType在方法签名中使用了类型参数。

扩展源码如下:

extension NSLayoutAnchor {
  open func constraint(to anchor: NSLayoutAnchor<AnchorType>, multiplier m: CGFloat) -> NSLayoutConstraint {
  // ...
  }
}
4

2 回答 2

6

注意:自 Swift 4 起已修复,请参阅下面的 benrudhart 的回答。

这是目前 swift 和 objc 的问题。不允许在 swift 中扩展 objc 泛型然后桥接回 objc。即使添加 a@nonobjc也不能解决问题。查看此处提交的错误:https ://bugs.swift.org/browse/SR-2708了解更多信息。

一个潜在的解决方法是对每种具体类型的NSLayoutAnchor. 具体类型NSLayoutXAxisAnchorNSLayoutYAxisAnchorNSLayoutDimension

extension NSLayoutDimension {
    open func constraint(to anchor: NSLayoutDimension, 
             multiplier m: CGFloat) -> NSLayoutConstraint
}

extension NSLayoutXAxisAnchor {
    open func constraint(to anchor: NSLayoutXAxisAnchor, 
             multiplier m: CGFloat) -> NSLayoutConstraint
}

extension NSLayoutYAxisAnchor {
    open func constraint(to anchor: NSLayoutYAxisAnchor, 
             multiplier m: CGFloat) -> NSLayoutConstraint
}
于 2017-03-09T17:36:22.157 回答
3

从 Swift 4 开始,现在可以通过使用@objc. 以下代码将编译:

@objc extension NSLayoutAnchor {
    func constraint(to anchor: NSLayoutAnchor<AnchorType>, multiplier: CGFloat) -> NSLayoutConstraint {
        // ...
    }
}
于 2017-10-25T07:05:55.963 回答