swift 协议,IBOutlet 属性不能有非对象类型
Posted
技术标签:
【中文标题】swift 协议,IBOutlet 属性不能有非对象类型【英文标题】:swift protocol, IBOutlet property cannot have non-object type 【发布时间】: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 没关系 - 你是说它是一个符合该协议的对象。 【参考方案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 的一个已知问题,因此可能有一天会解决。在那之前:
-
将委托声明为 AnyObject - @IBOutlet var delegate:AnyObject!
在 Interface Builder 中连接委托
将出口的类型更改为您的协议,例如@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 中拥有的实际对象的类型。
【讨论】:
以上是关于swift 协议,IBOutlet 属性不能有非对象类型的主要内容,如果未能解决你的问题,请参考以下文章