如何使用Swift泛型传递类型并返回该类型的对象?

时间:2015-04-16 12:20:07

标签: ios cocoa-touch swift

我正在编写一个函数,在给定类型的情况下,只需从磁盘中取消归档对象并将其作为该类型返回。这就是它的样子:

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
}

消费功能的计划方式是这样,它不起作用(我得到&#34;不能专门化非通用定义&#34;):

if let user = MQFileManager.objectWithFileName<User>("User", inFolder: .DocumentDirectory) {

}

如何正确关闭它?

3 个答案:

答案 0 :(得分:6)

如果指定了赋值的返回值的变量类型,则类型推断可以完成剩下的工作。因此,如果您有User类型,只需按如下方式调用该函数:

if let user: User = MQFileManager.objectWithFileName("User", inFolder: .DocumentDirectory) {

}

由于user变量属于User类型,编译器可以将T泛型推断为User类型

答案 1 :(得分:1)

您需要将类型传递给参数

public class func objectWithFileName<T>(fileName: String, inFolder folder: NSSearchPathDirectory, type:T.Type) -> T? {
    // Your function detail
}

然后像这样使用它

MQFileManager.objectWithFileName("User", inFolder: .DocumentDirectory, type:User.self)

答案 2 :(得分:0)

我制作了一个通用类来帮助我在Swift中使用经理文件,我相信这可以帮助你解决问题。

这是我的加载方法

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);
}

我将此代码上传到GitHub repository,有完整的课程

实施

通过这个课程,我打电话给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);

或其他简单模式,如果你一直保存同一个对象,建议采用这种方式,你不需要来自这个对象的很多对象。

 let mySaveClass = MySaveClass()
 TCFile.save(mySaveClass)
 let mySaveClassFromDisc = TCFile.loadFile(MySaveClass.self)