Быстрый протокол, свойство IBOutlet не может иметь неъектный тип
Я хотел бы подключить пользовательский быстрый делегат в IB. Делегат - это объект, который быстро реализует определенный протокол.
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?
^~~~~~~~~
Ответы
Ответ 1
Вы должны объявить свой ThumbnailTableViewCellDelegate
протокол как @objc
:
@objc protocol ThumbnailTableViewCellDelegate {
func cellWasTouched(thumbnail: Bool, cell: UITableViewCell)
}
Это потому, что @IBOutlet
объявляет переменную как weak
, которая работает только с объектами. Я не уверен, почему вы не можете просто сказать, что протокол соответствует AnyObject
, возможно, что ошибка Swift.
Ответ 2
Вы можете связать свои собственные протоколы в IB с этим обходным решением. Это известная проблема с Xcode, поэтому, вероятно, она будет решена в один прекрасный день. До тех пор:
- Объявить делегата как AnyObject - @IBOutlet var delegate: AnyObject!
- Подключить делегат в Interface Builder
- Измените тип выхода на свой протокол, например. @IBOutlet var delegate: MyDelegate
Это работает для меня.
Ответ 3
Переменная типа протокола может не быть объектом, потому что структуры и перечисления могут также соответствовать протоколам. Чтобы гарантировать соответствие протокола только классам, вы можете объявить протокол с помощью @class_protocol
.
Ответ 4
Не идеально, но вариант состоит в том, чтобы сделать что-то вроде этого:
@IBOutlet var objectType: NSObject!
private var conformingObject: SomeProtocol {
return objectType as SomeProtocol
}
Чтобы убедиться, что ваш objectType
соответствует SomeProtocol
или все взорвутся
Ответ 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.