首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Swift中降低/转换结构的泛型

如何在Swift中降低/转换结构的泛型
EN

Stack Overflow用户
提问于 2015-02-13 16:17:31
回答 1查看 3K关注 0票数 9

我已经将我与UICollectionViewCells的工作重构为以下内容

代码语言:javascript
复制
struct CollectionViewCellModel<T: UICollectionViewCell> {
    let reuseIdentifier: NSString
    let allowsSelection: Bool

    // Optional callbacks
    var onCreate: ((T) -> Void)?            = nil
    var onSelection: ((T) -> Void)?         = nil
    var onWillBeDisplayed: ((T) -> Void)?   = nil
    var onDelete: ((T) -> Void)?            = nil

    // Create cell
    func toCell(collectionView: UICollectionView, indexPath: NSIndexPath) -> T {
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as T
        if let onCreate = onCreate { onCreate(cell) }
        return cell
    }
}

这使得我更容易创建一个特定单元格的列表(比如表单),然后使用它们。

然而,在如何存储这些对象时,我总是会被绊倒。我不能将它们降到CollectionViewCellModel<UICollectionViewCell>,因此不能存储[CollectionViewCellModel<UICollectionViewCell>的列表

我以为斯威夫特支持向下投射,但显然不是一般类型的?

代码语言:javascript
复制
let cell = CollectionViewCellModel<A>(...)
let genericCell = cell as CollectionViewCellModel<UICollectionViewCell>
// ERROR: UICollectionViewCell is not identical to A
let genericMaybeCell = cell as? CollectionViewCellModel<UICollectionViewCell>
// ERROR: UICollectionViewCell is not identical to A

我是否必须将它们存储为一个Any数组,然后每次都进行转换,还是我只是误解了一些事情(或者两者兼而有之)?

更新:我在操场上做了一些工作,清楚地说明了我的意思:

代码语言:javascript
复制
protocol IA {
    func name() -> String
}

class A:IA { func name() -> String { return "A (Base)" } }
class B: A { override func name() -> String { return "B (Child of A)" } }
class C: B { override func name() -> String { return "C (Child of B)" } }

struct SA<T: A> {
}

let struct0: Any = SA<B>()
// OK: yes, the struct of B is an Any! 
// but since B inherits from A, isn't it safe to 
// say that SA<B> is also of type SA<A>?
let struct1: SA<A> = SA<B>() as SA<A>
// NO
// ERROR: 'B' is not identical to 'A'
let struct1Optional: SA<A> = SA<B>() as? SA<A>
// not even optionally? NO
// ERROR: 'B' is not identical to 'A'

我想这是不可能的。也许在斯威夫特1.3。请参阅注释中的线程。

最新情况(2/17/15)

对于那些对我为什么要这么做感兴趣的人来说,首先,你必须了解我是如何使用我的CollectionViewControllers (CVCs)的。我已经抽象出一个基本的CVC来执行每个屏幕需要的通用方法。这个CVC有一个协议,它需要一个Factory来创建CVC模型。这些模型知道如何转换自己,响应动作,并且非常像一个控制器。他们很胖而且很活跃。另一方面,我的观点都是愚蠢的。他们所知道的就是在屏幕上移动东西,或者进入不同的显示状态。当从CVC配置单元格时,您最终会执行这些大开关语句,从可读性的角度来看,这些语句实际上并没有告诉您多少期望“路由此”。更糟糕的是,您开始在其中配置视图。这并不可怕,但总的来说--对我来说--一个视图控制器控制着它所负责的视图。虽然这个VC可能是单元的父VC,但这并没有赋予它适当的权限来对其进行大量操作。这让你的VC做一些像cell.changeDisplayToActiveState()这样的事情;简而言之,它现在承担着控制自己的孩子细胞的负担。这就是所有“胖”风投的贡献所在。我首先选择通过采用VIPER模式来偏离这一路径,但我发现它过分了--特别是对于一个新的项目。我放弃了它,开始在一个基地CVC工作。目前,我的项目就是这样工作的:

  • 一个基CVC期望一个工厂&一个工厂期望一个CVC (因此促进了单元的双向绑定)
  • 这家工厂为CVC生产单元格和标头模型。
  • 这些模型中嵌入了回调&数据和配置功能。
  • 它们可以从这些回调(从而严格分离职责)(如vc.changeDisplayState(...)changeToVc(...) )中调用视图控制器的公共函数。
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-02-14 06:58:30

我不知道你到底在找什么,但我会尽力回答的。想必你对为某些特定的CollectionViewCellModel<X>存储一堆X不感兴趣,因为“我如何存储它们?”的答案很简单:[CollectionViewCellModel<X>]。因此,我猜您想要一个--您想要一个用于异构TCollectionViewCellModel<T>数组。实现这一点的最好方法是给您的CollectionViewCellModel<T>提供一个公共协议(或基类,但在您的情况下,它们是struct的,而不是那样的),大致如此:

代码语言:javascript
复制
protocol CollectionViewCellModelType {
  var reuseIdentifier: NSString {get}
  var allowsSelection: Bool {get}

  func toCell(
    collectionView: UICollectionView, indexPath: NSIndexPath
  ) -> UICollectionViewCell
}

struct CollectionViewCellModel<T: UICollectionViewCell>
  : CollectionViewCellModelType {
  let reuseIdentifier: NSString
  let allowsSelection: Bool

  // Optional callbacks
  var onCreate: ((T) -> Void)?            = nil
  var onSelection: ((T) -> Void)?         = nil
  var onWillBeDisplayed: ((T) -> Void)?   = nil
  var onDelete: ((T) -> Void)?            = nil

  // Create cell
  func toCell(
    collectionView: UICollectionView, indexPath: NSIndexPath
  ) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier(
      reuseIdentifier, forIndexPath: indexPath) as! T

    if let onCreate = onCreate { onCreate(cell) }
    return cell
  }
}

var a: [CollectionViewCellModelType] = [] // put them in here

希望这能帮上忙

戴夫

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28503963

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档