如何将未知结构传递给函数 - swift 3, IOS10

How to pass an unknown struct to a function - swift 3, IOS10

这将是我在 Whosebug 上的第一个问题,也是我在 Swift 上提出的第一个问题 3;我是一个初学者,也许咬得太多了,但是...

我正在尝试创建一个 class,它将协助创建菜单项(class 称为 'MenuItems')以填充到我的动态 table IOS 申请。我已经创建了 class 的主体,它从传递给它的数据中识别出 headers 是什么,以及每种类型中有多少将被分成 table 中的部分。我现在正处于尝试使 class 更通用的阶段,以便它适用于我将来可能希望填充到类似 table 中的不同数据结构。

我希望 table 中的数据来自其自身 swift 文件中的结构。它看起来像这样:

struct EquipmentStruct {
    var name : String!
    var serialNumber : String?
    var alias : String?
    var image : UIImage?
}

我有一个 EquipmentStruct 类型的数组,短期内,它在我的 tableViewController 文件中初始化(以后不会留在这里),我希望创建一个public 函数在我的 MenuItems class 中允许我根据需要向 table 添加一个项目

func addItem(item, dataType) // types for item and dataType are part of my question

在设计这个功能的过程中我发现了我的问题:

  1. 如何将 EquipmentStruct 类型的变量传递到我的 MenuItems class 的实例,以便我可以将它添加到我的 table - 请注意,我要问的只是用于指导如何完成 addItem 方法,而不是 class 的其余部分。在我看来,我想做类似的事情:

    var dataArray : [EquipmentStruct] =
    [EquipmentStruct(name: "SA80",  serialNumber:"01234-56-789", alias: "29", image: #imageLiteral(resourceName: "SA80")),
     EquipmentStruct(name: "LSW",  serialNumber:"11111-22-333-4444", alias: "98", image: #imageLiteral(resourceName: "LSW"))]
    
    var tableMenuItems = MenuItems() // create instance of class MenuItems
    
    override func viewDidLoad() {
    
    super.viewDidLoad()        
    
    for var itemNumber in 0..<dataArray.count{
        tableMenuItems.addItem(item: generalHoldingsDataArray[itemNumber], dataType: EquipmentStruct)
    }
    

addItems 方法原型因此类似于:

// Add new item of type 'dataType' to MenuItems.tableDataArray
// Store tableDataArrayType for use throughout the class
//
func addItem(item: [Something], dataType: SomeVariableType){
    if let newItem = item as! dataType{ // cast the variable received to its type
        tableDataArrayType = dataType
        tableDataArray.append(newItem)
    }
}

  1. 这样做事好吗?

  2. 有没有更简单的方法来完成我想做的事情?

  3. 如果我继续沿着这条路走下去,我将来可能会遇到什么问题?

非常感谢您的帮助。

亲切的问候

一个 table 视图应该只包含一种类型的东西作为模型。单个 table 视图并非旨在显示有关 EquipmentStructSomeOtherStruct 和 3 个 Foo 的信息。您必须将所有这些概括为一种类型。

另一种可能性是您想要创建一个 MenuItems 类型,它可以创建一个显示 EquipmentStructs 的 table 视图,一个显示 SomeOtherStructs,基本上是一个显示您喜欢的任何类型的 table 视图。如果是这种情况,您应该使用 generics.

MenuItems class 像这样:

class MenuItems<T : SomeProtocol> {
    var tableDataArray: [T] = []

    func addItem(_ newItem: T) {
        tableDataArray.append(newItem)
    }
    // ...
    // since you just need guidance on creating addItems method, figure the rest yourself please! XD
}

要创建一个显示 EquipmentStruct 的 table 视图,

let tableMenuItems = MenuItems<EquipmentStruct>()

要创建一个显示 SomeOtherStruct 的 table 视图,

let tableMenuItems = MenuItems<SomeOtherStruct>()

注意到第一行的 SomeProtocol 了吗?这定义了 properties/methods 类型应该具有的内容,以便在 table 视图中显示。可能的 SomeProtocol 可能是:

protocol SomeProtocol {
    var displayTitle: String { get }
    var displaySubtitle: String? { get }
    var displayImage: UIImage? { get }
}

这只是确保要在 table 视图中显示的类型具有名为 displayTitledisplaySubtitledisplayImage 的属性。您可以在 MenuItems class 中使用这些属性来设置 table 视图单元格的外观。