2015-02-23 4 views
1

Я пытаюсь создать делегат, который использует традиционный полиморфизм, чтобы компенсировать устройство, являющееся bluetooth LE, bluetooth и т. Д., И, похоже, не может получить синтаксис для кастинга.Использование Swift Protocol Inheritance

Вот мой родительский протокол и класс:

@objc protocol DeviceDelegate 
{ 
    func didConnectToDevice(name:String) 
    func didFailToConnectToDevice(name:String) 
    func didDisconnectFromDevice(name:String) 

    func didWriteData(data:NSData) 
    func didReceiveData(data:NSData) 
} 

class Device: NSObject 
{ 
    var delegate: DeviceDelegate? 
} 

Теперь вот дочерний класс и протокол упрощен вниз:

protocol BluetoothDelegate : DeviceDelegate 
{ 
    func didFindService(name:String) 
    func didFindCharacteristic(name:String) 
} 

class BLE: Device 
{ 
    func someFunc() 
    { 
     let bluetoothDelegate = (delegate as? BluetoothDelegate) 
     bluetoothDelegate.didFindService(UUIDString) 
    } 
} 

Он выдает следующее сообщение об ошибке в первой строке этой функции:

Cannot downcast from 'DeviceDelegate?' to [email protected] protocol type 'BluetoothDelegate' 

Это не имеет смысла для меня, так как это должно допускать литье в ac как обычный объект.

Если я ставлю @objc перед BluetoothDelegate я получаю следующее сообщение об ошибке:

@objc protocol 'BluetoothDelegate' cannot refine [email protected] protocol 'DeviceDelegate' 

Кто-нибудь есть какие-либо идеи по этому поводу?

ответ

1

Когда я скопировать код и вставить его в игровую площадку и добавить @objc перед вашим BluetoothDelegate определения, я получаю сообщение об этой линии:

bluetoothDelegate.didFindService("asdf") 

'BluetoothDelegate?' does not have a member named 'didFindService'

Поскольку вы использовали as?, есть вероятность, что bluetoothDelegate - nil. Здесь вы должны использовать дополнительную цепочку. Замена следующей строкой не приводит к ошибкам на игровой площадке, что указывает на то, что вы, возможно, сделали что-то еще в своем коде, который вы нам не показываете.

bluetoothDelegate?.didFindService("asdf") 

В качестве альтернативы, вы можете использовать это:

if let bluetoothDelegate = delegate as? BluetoothDelegate { 
    bluetoothDelegate.didFindService(UUIDString) 
} 

сообщение, которое вы видите о DeviceDelegate не будучи ObjC протокол указывает мне, что вы написали это в двух разных файлах и возможно, заранее объявлено DeviceDelegate.

+0

Я использую ваш альтернативный код и получаю тот же результат, НО: Они находятся в двух отдельных файлах, потому что они используются родительским и дочерним классами соответственно. Я думаю, что это может быть ошибка компилятора, если я переношу оба протокола в один файл, тогда он компилируется правильно. Пошел на конечность и протестировал недавно выпущенный XCode 6.3 Beta 2, и он отлично работает с ним в двух отдельных файлах. Спасибо! – Khirok