【问题标题】:Working with array with different data types in Swift在 Swift 中使用具有不同数据类型的数组
【发布时间】:2018-05-16 09:21:17
【问题描述】:

我正在开发一个能够播放歌曲播放列表的音乐应用程序,我的项目中有两种数据类型代表一首歌曲; “Track”是 NSManagedObject 的,用于用户保存在设备上的歌曲,“JSONTrack”表示可从 json Web 服务解码的歌曲。用户应该能够将这两种类型添加到播放列表数组中。如何使用 Swift 实现这一点,为不同的数据类型创建一个数组并在该数组上工作: 我当前处理其中一种数据类型的代码如下所示:

var playlistTracks = [Track]()

@objc fileprivate func handlePrevTrack() {
    if playlistTracks.isEmpty {
        return
    }

    let currentTrackIndex = playlistTracks.index { (tr) -> Bool in
        return self.track?.trackTitle == tr.trackTitle && self.track?.albumTitle == tr.albumTitle
    }

    guard let index = currentTrackIndex else { return }

    let prevTrack: Track

    if index == 0 {
        let count = playlistTracks.count
        prevTrack = playlistTracks[count - 1]
    } else {
        prevTrack = playlistTracks[index - 1]
    }

    self.track = prevTrack
}

@objc func handleNextTrack() {
    if playlistTracks.count == 0 {
        return
    }

    let currentTrackIndex = playlistTracks.index { (tr) -> Bool in
        return self.track?.trackTitle == tr.trackTitle && self.track?.albumTitle == tr.albumTitle
    }

    guard let index = currentTrackIndex else { return }

    let nextTrack: Track
    if index == playlistTracks.count - 1 {
        nextTrack = playlistTracks[0]
    } else {
        nextTrack = playlistTracks[index + 1]
    }

    self.track = nextTrack

}

处理下一个和上一个选择。我想对由两种不同数据类型表示的两种不同类型的歌曲执行相同的操作。

【问题讨论】:

    标签: ios arrays swift


    【解决方案1】:

    使用具有下一步和先前操作所需的方法/属性的协议。让您的两种轨道类型都实现该协议。让您的数组具有协议的类型。

    protocol Track {
        title: String
        albumTitle: String
        // other method and properties
    }
    
    class JSONTrack: Track {
        // implementation
    }
    
    class CoreDataTrack: Track {
        // implementation
    }
    
    let tracks = [Track]()
    

    【讨论】:

    • 我打算建议这个,甚至是enum,它可能是一种或另一种类型。我想我更喜欢这个协议:D
    • 但是我的CoreDataTrack是NSManagedObject的,Xcode通常不想编辑那些自动生成的文件,我还能让它符合协议吗?
    • 好的,我找到了一种手动生成 CoreData 模型类的方法,这样我就可以自定义它们以使它们采用协议。谢谢
    【解决方案2】:

    这里有多种解决您的问题的方法

    1。使用协议

    您可以使JSONTrackTrack 都符合名为TrackProtocol 的协议,例如具有通用方法名称。然后你可以无缝地操作你的TrackProtocol 数组。

    最佳解决方案

    2。使用枚举

    创建一个包含两者的TrackEnum 枚举。

    enum TrackEnum {
        case json(JSONTrack)
        case coreData(Track)
    }
    

    那么你的数组是TrackEnum 的数组,你每次提取它是哪一个。

    3。使用任意

    您可以创建一个Any 数组并在运行时检查内容类型。

    最坏的解决方案。

    【讨论】:

      【解决方案3】:

      使用协议可能是最常见的,但enum 也很有效。

      详细说明enum 选项:

      class JSONTrack: NSObject {}
      class OtherTrack: NSObject {}
      
      enum Track {
          case jsonTrack(JSONTrack)
          case otherTrack(OtherTrack)
      
          // enum can be handy if you want to do type checking
          // and e.g. present specific data for that type
          var label: String {
              switch self {
              case .jsonTrack:
                  return "Json track"
              case .otherTrack:
                  return "Other track"
              }
          }
      }
      
      let jsonTrack = JSONTrack()
      let otherTrack = OtherTrack()
      let tracks: [Track] = [Track.jsonTrack(jsonTrack), Track.otherTrack(otherTrack)]
      
      let labelOfTrack1 = tracks.first!.label
      print(labelOfTrack1)
      // prints "Json track"
      

      【讨论】:

        猜你喜欢
        • 2015-12-19
        • 1970-01-01
        • 1970-01-01
        • 2019-07-24
        • 2015-07-10
        • 1970-01-01
        • 2020-04-09
        • 2017-10-09
        • 2020-11-05
        相关资源
        最近更新 更多