[英]How to use Swift generics to pass a type and return an object as that type?
I'm writing a function that, given a type, simply unarchives an object from the disk and returns it as that type. 我正在编写一个函数,给定一个类型,只需从磁盘中取消归档对象并将其作为该类型返回。 This is what it looks like:
这就是它的样子:
public class func objectWithFileName<T>(fileName: String, inFolder folder: NSSearchPathDirectory) -> T? {
// Build an NSURL var called fileURL based on the fileName and folder.
// ...
// If any object was found
if let object: AnyObject = NSKeyedUnarchiver.unarchiveObjectWithFile(fileURL.path!) {
// Attempt to return the object as an object of type T.
if let typedObject = object as? T {
return typedObject
}
}
return nil
}
The planned way of consuming the function is this, and it doesn't work (I'm getting "Cannot specialize a non-generic definition"): 计划使用函数的方法是这样,它不起作用(我得到“不能专门化非泛型定义”):
if let user = MQFileManager.objectWithFileName<User>("User", inFolder: .DocumentDirectory) {
}
How can I pull this off correctly? 我怎样才能正确拉出它?
If you specify the type of the variable the return value is assigned to, type inference can do the rest. 如果指定返回值的变量类型,则可以执行其余类型推断。 So if you have a
User
type, simply invoke the function as follows: 因此,如果您有
User
类型,只需按如下方式调用该函数:
if let user: User = MQFileManager.objectWithFileName("User", inFolder: .DocumentDirectory) {
}
Since the user
variable is of User
type, the compiler can infer the T
generic to be of User
type 由于
user
变量属于User
类型,因此编译器可以将T
generic推断为User
类型
You need pass the type into the arguments 您需要将类型传递给参数
public class func objectWithFileName<T>(fileName: String, inFolder folder: NSSearchPathDirectory, type:T.Type) -> T? {
// Your function detail
}
Then using it like this 然后像这样使用它
MQFileManager.objectWithFileName("User", inFolder: .DocumentDirectory, type:User.self)
I made a generic class to help me manager file in Swift, I believe this can help you with your question. 我创建了一个通用类来帮助我在Swift中管理文件,我相信这可以帮助你解决问题。
It is my load method 这是我的加载方法
static func loadFile<T:TCFileData>(#name:String, classType:T.Type)->T!
{
var data:T?;
if(hasFile(name: name))
{
if let rawData = NSData(contentsOfFile: getPath(name) as String) {
var object: AnyObject? = NSKeyedUnarchiver.unarchiveObjectWithData(rawData);
data = object as? T;
}
}
return data;
}
static func loadFile<T:TCFileData>(classType:T.Type)->T!
{
return loadFile(name: getFileName(classType), classType:classType);
}
I upload this code to GitHub repository , there has complete class 我将此代码上传到GitHub存储库 ,有完整的类
With this class, I called TCFile, you can implement this way to save many class in your drive 通过这个类,我调用了TCFile,你可以用这种方式在驱动器中保存很多类
//TCFileData is a "protocol" to save with TCFile
class MySaveClass:TCFileData
{
//implement your class with NSCode and NSCoding pattern
}
TCFile.save(name:"someId", object: MySaveClass());
let mySaveClass = TCFile.loadFile(name:"someId", classType: MySaveClass.self);
or other simple mode, this way is recommended in case you save the same object all time, you don't need many object from this object. 或者其他简单模式,如果你一直保存同一个对象,建议采用这种方式,你不需要来自这个对象的很多对象。
let mySaveClass = MySaveClass()
TCFile.save(mySaveClass)
let mySaveClassFromDisc = TCFile.loadFile(MySaveClass.self)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.