首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >保存文件管理器

保存文件管理器
EN

Code Review用户
提问于 2015-04-16 13:51:43
回答 1查看 743关注 0票数 4

我用Swift创建了一个类来管理在驱动器中保存的文件,并且我试图做最好的工作。

有人能给我一个关于这门课的反馈吗?我还能改进什么?这是保存文件的好方法吗?

代码语言:javascript
复制
import UIKit

class TCFileData:NSObject, NSCoding
{
    override init() {
    }

    required init(coder aDecoder: NSCoder) {
    }

    func encodeWithCoder(aCoder: NSCoder) {
        fatalError("encodeWithCoder(aCoder: NSCoder:) has not been implemented");
    }
}

struct TCFile {

    static func save<T:TCFileData>(#name:String, object:T)->Bool
    {
        let path = getPath(name);
        let saveData = NSKeyedArchiver.archivedDataWithRootObject(object);
        return saveData.writeToFile(path as String, atomically: true);
    }

    static func save<T:TCFileData>(object:T)->Bool
    {
        return save(name: NSStringFromClass(object.classForCoder), object: object);
    }

    static func hasFile(#name:String)->Bool
    {
        return NSFileManager.defaultManager().fileExistsAtPath(getPath(name) as String);
    }

    static func hasFile<T:TCFileData>(classType:T.Type)->Bool
    {
        return hasFile(name: getFileName(classType));
    }

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

    static func loadFile<T:TCFileData>()->T!
    {
        return loadFile(name: getFileName(T.self), classType:T.self);
    }

    static func remove(#name:String)->Bool
    {
        if(hasFile(name: name))
        {
            return NSFileManager.defaultManager().removeItemAtPath(getPath(name) as String, error: nil);
        }

        return false;
    }

    static func remove<T:TCFileData>(classType:T.Type)->Bool
    {
        return remove(name: getFileName(classType));
    }

    static private func getPath(file:String)->NSString
    {
        let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) as NSArray;
        let documentsDirectory = paths.objectAtIndex(0) as! NSString;
        let path = documentsDirectory.stringByAppendingPathComponent(file);
        return path;
    }

    static private func getFileName<T:TCFileData>(classType:T.Type)->String
    {
        return NSStringFromClass(classType.self.classForCoder());
    }
}
EN

回答 1

Code Review用户

回答已采纳

发布于 2015-04-16 20:32:32

你的组织有点混乱。

TCFileData是一种强行将抽象类强制转换为没有抽象类的语言的黑客尝试,而TCFile则试图为一种没有名称空间的语言创建命名空间,这里似乎没有必要使用泛型。

我认为这里更有意义的是完全消除class并使struct更像一个包装器对象。class的问题是,它不必要地消除了使用大量现有对象的文件管理代码,这些对象已经符合NSCoding (这就是您实际需要的代码)。

我们想要一个class,它一开始看起来是这样的:

代码语言:javascript
复制
class TCFileManager<T: NSCoding> {
    var contents: T?
    var path: String

    init(path: String, contents: T? = nil) {
        self.path = path
        self.contents = contents
    }
}

现在,从这里开始,我们实现了struct已经实现的所有方法,但它们大多不接受参数或返回任何内容。相反,它们对其属性使用set值,并设置这些值。

因此,例如,我们可能希望将我作为plist保存的字典加载到桌面上:

代码语言:javascript
复制
let fileManager = TCFileManager<NSDictionary>(path: "/Users/nhgrif/Desktop/myPlist.plist")
fileManager.load()
let plist = fileManager.contents

当然,除了设置load属性之外,我们还可以将.contents设置为返回加载的对象,但是您可以获得gist。

一旦我们用路径实例化了文件管理器对象,一小组方法就可以使很多事情更容易完成。

考虑一下,我们还可以有一个move方法,它为要将文件移动到的路径接受一个字符串参数。该方法将首先执行您期望的操作(移动文件),但随后对象的path属性将更改到传入的路径。

显然,您也希望实现一个save方法,等等。

但我认为将代码转换成这种形状会使许多事情变得更有意义,而且更容易使用。

票数 4
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/87084

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档