Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift-使用泛型改进类中的计算属性_Swift_Generics_Frontend_Computed Properties - Fatal编程技术网

Swift-使用泛型改进类中的计算属性

Swift-使用泛型改进类中的计算属性,swift,generics,frontend,computed-properties,Swift,Generics,Frontend,Computed Properties,我在视图类中有以下代码块: private var notes: [String] = [] { didSet { if notes.count > 0, notes.count == (oldValue.count + 1) { tableView.insertRows(at: [IndexPath.init(row: 0, section: 3)], with: .right) } else { tableView.rel

我在视图类中有以下代码块:

private var notes: [String] = [] {
    didSet {
      if notes.count > 0, notes.count == (oldValue.count + 1) {
        tableView.insertRows(at: [IndexPath.init(row: 0, section: 3)], with: .right)
      } else {
        tableView.reloadData()
      }
    }
  }

private var images: [UIImage?] = [] {
  didSet {
    if images.count > 0, images.count == (oldValue.count + 1) {
      tableView.insertRows(at: [IndexPath.init(row: 0, section: 2)], with: .right)
    } else {
      tableView.reloadData()
    }
  }
}

private var urls: [URL?] = [] {
  didSet {
    if urls.count > 0, urls.count == (oldValue.count + 1) {
      tableView.insertRows(at: [IndexPath.init(row: 0, section: 1)], with: .right)
    } else {
      tableView.reloadData()
    }
  }
}
它的工作原理非常棒,但我看到了这一点,我马上就想改进它,因为它几乎是完全相同的东西的三倍。。我在Java中使用了一些泛型,我已经阅读了Swift中泛型的文档,但是我不能完全让它工作。我想最终做一些类似的事情

private var items: [T] = [] {
  didSet {
    if items.count > 0, items.count == (oldValue.count + 1) {
      tableView.insertRows(at: [IndexPath.init(row: 0, section: 1)], with: .right)
    } else {
      tableView.reloadData()
    }
  }
}
这样我就可以把它们都放在一个区域里。这可能吗?我还是个新手,所以我非常感谢任何帮助,即使这对你来说是个简单的问题:)


谢谢

我认为这里的问题是,与许多语言不同,在Swift中,数组类型本身是泛型的。您可以将数组放入包装器结构中,generic over T,这将允许您实现setter

struct MyArray<T> {
   var items: [T] = [] {
      didSet {
         if items.count > 0, items.count == (oldValue.count + 1) {
            //something
         } else {
            //something else
         }
      }
   }
}
struct MyArray{
变量项:[T]=[]{
迪塞特{
如果items.count>0,items.count==(oldValue.count+1){
//某物
}否则{
//别的
}
}
}
}
然后,如果愿意,您可以包装所有常用方法,或者编写一个迭代器并遵循序列以获得所有默认方法。
这是否值得处理包装的开销,我将留给您;-)

你可以用一个简单的函数来解决这个问题

private func updateTable(count: Int, oldCount: Int, section: Int) {
    if count > 0, count == (oldCount + 1) {
        tableView.insertRows(at: [IndexPath.init(row: 0, section: section)], with: .right)
    } else {
        tableView.reloadData()
    }
}
这将使代码简化为

private var notes: [String] = [] {
    didSet {
        updateTable(count: notes.count, oldCount: oldValue.count, section: 3)
    }
}
另一个选项是传递数组

private func updateTable(array: [Element], oldArray: [Element], section: Int) {
    if array.count > 0, array.count == (oldArray.count + 1) {
        tableView.insertRows(at: [IndexPath.init(row: 0, section: section)], with: .right)
    } else {
        tableView.reloadData()
    }
}

啊,谢谢!不知道数组是通用的,谢谢!:)我认为这是一个非常好的答案,但请注意,在原始代码中,
部分
会根据每个变量进行更改。这实际上为基于函数的方法提供了一个更有力的理由,但展示这一点会有所帮助。此外,也不需要传递数组(它可以工作,但如果可以的话,它会强制进行不必要的复制)。您需要将
updateTable
设置为通用:
func updateTable(new:[Element],old:[Element],section:Int)
@RobNapier感谢您指出该部分已更改,我完全错过了。您是对的,通用解决方案更适合于阵列版本。但检查
notes.count>0
是多余的。如果第二次检查成功,
不为空。