【问题标题】:swift protocol, IBOutlet property cannot have non-object typeswift 协议,IBOutlet 属性不能有非对象类型
【发布时间】:2014-07-03 19:04:39
【问题描述】:

我想在 IB 中连接一个自定义 swift 委托。委托是一个快速实现特定协议的对象。

protocol ThumbnailTableViewCellDelegate {
    func cellWasTouched(thumbnail: Bool, cell: UITableViewCell)
}

class ThumbnailTableViewCell: UITableViewCell {
    @IBOutlet var thumbnailTableViewCellDelegate: ThumbnailTableViewCellDelegate?
}

不幸的是,编译器抱怨:

error: 'IBOutlet' property cannot have non-object type 'ThumbnailTableViewCellDelegate'
    @IBOutlet var thumbnailTableViewCellDelegate: ThumbnailTableViewCellDelegate?
    ^~~~~~~~~

【问题讨论】:

  • @Andy 没关系 - 你是说它是一个符合该协议的对象。

标签: ios interface-builder swift


【解决方案1】:

您必须将您的ThumbnailTableViewCellDelegate 协议声明为@objc

@objc protocol ThumbnailTableViewCellDelegate {
    func cellWasTouched(thumbnail: Bool, cell: UITableViewCell)
}

这是因为@IBOutlet 将变量声明为weak,它只适用于对象。我不知道为什么你不能只说协议符合AnyObject,也许那是一个 Swift 错误。

【讨论】:

  • 感谢 Nate,这很有效!这是临时解决方法还是预期行为?在这种情况下@objc 的相关性是什么?
  • 这个方法不再适用于我(使用 Xcode 6 的 GM 种子)
  • 这可以编译,但我现在在连接故事板中的插座时遇到了问题
  • 是的,在 xcode 6.2 上也是如此……有人解决了这个问题吗?
  • 您可以使用下面 Morten J 的解决方法,或者在代码中手动设置委托,而不是在情节提要中。如果你还没有引用 ThumbnailTableViewCell,你必须先创建一个 outlet。
【解决方案2】:

您可以使用此解决方法在 IB 中连接您自己的协议。这是 Xcode 的一个已知问题,因此可能有一天会解决。在那之前:

  1. 将委托声明为 AnyObject - @IBOutlet var delegate:AnyObject!
  2. 在 Interface Builder 中连接委托
  3. 将出口的类型更改为您的协议,例如@IBOutlet var delegate:MyDelegate

这对我有用。

【讨论】:

  • 是否有已知的雷达或发行说明记录了这一点?
【解决方案3】:

不理想,但一种选择是做这样的事情:

@IBOutlet var objectType: NSObject!

private var conformingObject: SomeProtocol {
  return objectType as SomeProtocol
}

必须确保你的 objectType 符合 SomeProtocol 否则事情会爆炸

【讨论】:

    【解决方案4】:

    协议类型的变量可能不是对象,因为结构和枚举也可以符合协议。为确保协议只能由类遵守,您可以使用@class_protocol 声明该协议。

    【讨论】:

      【解决方案5】:

      IB 需要 AnyObject,而不是您的特定协议,这是有道理的。您想要连接的对象可能但不一定符合协议,并且协议可能有选项 - 所以:

      让你的协议像这样:

      @objc public protocol HexViewDataSource: NSObjectProtocol {
          @objc optional func dataAtOffset (_ hexView: HexView, offset: UInt64, length: Int)-> Data?
          @objc optional func dataLength (_ hexView: HexView) -> UInt64
      }
      

      像这样在你的类中声明它,例如:

      @IBOutlet weak open var dataSource: AnyObject?
      

      当您开始使用它时,请检查它是否符合协议以及是否存在可选选项 - 像这样:

      if let dataSource = dataSource as? HexViewDataSource, let dfr = dataSource.dataAtOffset {
          setRowData(offset: offset, data: dfr (self, offset, bytesPerRow))
      }
      

      【讨论】:

        【解决方案6】:

        IBOutlets 用于指示指向存储在 nib(或故事板)文件中的对象的指针。协议不是对象,因此您不能在 nib 文件中包含一个对象。将 IBOutlet var 的类型设为您在 nib 中拥有的实际对象的类型。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-10-26
          • 2018-05-21
          • 1970-01-01
          • 2016-02-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多