我有一个从属性列表中加载字典数组的方法。然后我将这些字典数组更改为定义的自定义类型的数组; 我想用泛型形式编写该方法,所以我用我期望的类型调用该方法,然后方法加载它并返回我的自定义类型的数组而不是字典
func loadPropertyList(fileName: String) -> [[String:AnyObject]]?
{
if let path = NSBundle.mainBundle().pathForResource(fileName, ofType: "plist")
{
if let plistXML = NSFileManager.defaultManager().contentsAtPath(path)
{
do {
if let temp = try NSPropertyListSerialization.propertyListWithData(plistXML, options: .Immutable, format: nil) as? [[String:AnyObject]]
{
return temp
}
}catch{}
}
}
return nil
}
//
func loadList<T>(fileName: String) -> [T]?{//**Here the answer I am expecting**}
答案 0 :(得分:1)
我假设您的功能是从Plist中读取作品而您不想要继承NSObject
。
由于Swift反射不支持设置值,因此如果没有您想要的每种类型的实现,这是不可能的。
然而,它可以以一种非常优雅的方式完成。
struct PlistUtils { // encapsulate everything
static func loadPropertyList(fileName: String) -> [[String:AnyObject]]? {
if let path = NSBundle.mainBundle().pathForResource(fileName, ofType: "plist") {
if let plistXML = NSFileManager.defaultManager().contentsAtPath(path) {
do {
if let temp = try NSPropertyListSerialization.propertyListWithData(plistXML, options: .Immutable, format: nil) as? [[String:AnyObject]] {
return temp
}
} catch {
return nil
}
}
}
return nil
}
}
此协议将以通用方式使用以获取类型名称并读取相应的Plist。
protocol PListConstructible {
static func read() -> [Self]
}
此协议将用于实现键值设置器。
protocol KeyValueSettable {
static func set(fromKeyValueStore values:[String:AnyObject]) -> Self
}
这是两者的组合,用于生成对象数组。这确实要求Plist以Type类型命名。
extension PListConstructible where Self : KeyValueSettable {
static func read() -> [Self] {
let name = String(reflecting: self)
var instances : [Self] = []
if let data = PlistUtils.loadPropertyList(name) {
for entry in data {
instances.append(Self.set(fromKeyValueStore: entry))
}
}
return instances
}
}
这是一些类型。
struct Some : PListConstructible {
var alpha : Int = 0
var beta : String = ""
}
您所要做的就是实现Key Value setter,现在可以从Plist中读取它。
extension Some : KeyValueSettable {
static func set(fromKeyValueStore values: [String : AnyObject]) -> Some {
var some = Some()
some.alpha = (values["alpha"] as? Int) ?? some.alpha
some.beta = (values["beta"] as? String) ?? some.beta
return some
}
}
这就是你使用它的方式。
Some.read()