在 Swift 中使用具有不同数据类型的数组
Posted
技术标签:
【中文标题】在 Swift 中使用具有不同数据类型的数组【英文标题】:Working with array with different data types in 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
处理下一个和上一个选择。我想对由两种不同数据类型表示的两种不同类型的歌曲执行相同的操作。
【问题讨论】:
【参考方案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。使用协议
您可以使JSONTrack
和Track
都符合名为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"
【讨论】:
以上是关于在 Swift 中使用具有不同数据类型的数组的主要内容,如果未能解决你的问题,请参考以下文章