首页 > 解决方案 > 对协议关联类型的可选强制转换失败(返回 nil)

问题描述

我的开源库中有一个协议(链接以防万一的代码示例是不够的)。

所述协议有两种关联类型,一种用于函数“发送”类型,另一种用于定义如下的“返回类型”:

/// A protocol which can be adopted to define a function that can be performed on any given camera
public protocol CameraFunction {

    /// An associated type which is taken as an input when calling this function on a `Camera` instance
    associatedtype SendType

    /// An associated type which is returned from the camera when calling this function on the `Camera`
    associatedtype ReturnType

    /// The enum representation of this given function
    var function: _CameraFunction { get }
}

在函数实现中(performFunction在另一个协议上声明):

func performFunction<T>(_ function: T, payload: T.SendType?, callback: @escaping ((Error?, T.ReturnType?) -> Void)) where T : CameraFunction {

        switch function.function {
        case .getEvent:
            let packet = Packet.commandRequestPacket(code: .getAllDevicePropData, arguments: [0], transactionId: ptpIPClient?.getNextTransactionId() ?? 0)
            ptpIPClient?.awaitDataFor(transactionId: packet.transactionId, callback: { (dataResult) in

                switch dataResult {
                case .success(let data):
                    guard let numberOfProperties = data.data[qWord: 0] else { return }
                    var offset: UInt = UInt(MemoryLayout<QWord>.size)
                    var properties: [PTPDeviceProperty] = []
                    for _ in 0..<numberOfProperties {
                        guard let property = data.data.getDeviceProperty(at: offset) else { break }
                        properties.append(property)
                        offset += property.length
                    }
                    let event = CameraEvent(sonyDeviceProperties: properties)
                    callback(nil, event as? T.ReturnType)
                case .failure(let error):
                    callback(error, nil)
                }
            })
            ptpIPClient?.sendCommandRequestPacket(packet, callback: nil)

我创建了一个CameraEvent对象并尝试向下转换(不确定这是否是正确的术语)到T.ReturnType. 在被调用的地方,eventis non-nil,但是将其转换为即使它应该匹配也会T.ReturnType给出结果!nil

Event.get(.getEvent) 的定义如下:

/// Functions for interacting with the event API on the camera
public struct Event: CameraFunction {

    public var function: _CameraFunction

    public typealias SendType = Bool

    public typealias ReturnType = CameraEvent

    /// Gets the current event
    public static let get = Event(function: .getEvent)
}

还需要注意的是,我谈到的第二个协议的另一个实现(定义performFunction函数的那个​​)成功地做了非常相似的逻辑,我没有得到 nil 回来!一定有什么我做错了,但我不知道它可能是什么!

截图以防万一!

调用协议的函数

调用协议函数

协议功能的实现

协议功能的实现

标签: iosswiftgenericsprotocolsswift-protocols

解决方案


这......只是调试器是一堆垃圾!决定添加一个print声明以绝对确定它是nil。事实证明并非如此!打印很好,但lldb似乎无论出于何种原因都认为它为零。


推荐阅读