使用它的通用 ObjectType 的 PHFetchResult 扩展?

Mik*_*dar 3 generics extension-methods swift phphotolibrary swift4

我正在尝试向 PHFetchResult 添加扩展以将结果对象作为正确类型的数组拉出 - 到目前为止我无法弄清楚如何避免下面看到的复制。除了类型约束之外,以下扩展是相同的。如果我使用 PHObject 作为约束,它会起作用,但结果需要转换为更具体的类型......

extension PHFetchResult where ObjectType == PHAsset {
    var objects: [ObjectType] {
        var _objects: [ObjectType] = []
        enumerateObjects { (object, _, _) in
            _objects.append(object)
        }
        return _objects
    }
}    
extension PHFetchResult where ObjectType == PHCollection {
    var objects: [ObjectType] {
        var _objects: [ObjectType] = []
        enumerateObjects { (object, _, _) in
            _objects.append(object)
        }
        return _objects
    }
}    
extension PHFetchResult where ObjectType == PHAssetCollection {
    var objects: [ObjectType] {
        var _objects: [ObjectType] = []
        enumerateObjects { (object, _, _) in
            _objects.append(object)
        }
        return _objects
    }
}
Run Code Online (Sandbox Code Playgroud)

ric*_*ter 5

这是在 ObjC 中定义并导入到 Swift 的泛型类型的普遍问题。一些相关的编译器错误:

简而言之:ObjC 泛型是类型擦除的,Swift 泛型是类型保留的。您需要后者来执行诸如定义类型约束扩展之类的任务,但您不能这样做,因为 Swift 对任何特定PHFetchResult实例的 ObjectType 一无所知。

将 ObjC 泛型导入广泛引入 Swift 3 的 swift-evolution 提案包括一项规定,让 ObjC 类在运行时提供有关其泛型类型参数的信息……但截至今天,该规定从未实现。

AFIAK,这个问题并没有真正的解决方案(没有在 Swift 编译器项目上工作以改进 ObjC 泛型支持),也没有类似的问题,例如使PHFetchResult符合Sequence或Collection.

(我已经尝试了几个角度来扩展 PhotoKit 类以使其更加 Swifty,但没有取得多大成功。关于我唯一没有尝试的事情 - 主要是因为它是如此激烈的措施 - 是包装/替换大块 API。不过,理论上,您可以包装PHFetchResult在一个非通用的 ObjC 类中,然后将它包装在一个通用的 Swift 类型中,并将所有 PhotoKit fetch 方法替换为提供您的包装类型的适当专用版本的方法。)