存储泛型

时间:2015-08-05 21:08:09

标签: swift generics

所以我正在编写一个使用Argo库来解析我们的JSON的应用程序。效果很好。但是,我正试图找到一种方法来缓存我们得到的解析类型。它们都是作为结构实现的。我试过这样的事情:

struct CachedItem <T: Decodable where T == T.DecodedType> {
    let value: T
    let cachedTime: NSTimeInterval

    init(value: T) {
        self.value = value
        cachedTime = NSDate().timeIntervalSince1970
    }

    func isExpired() -> Bool {
        let currentTime = NSDate().timeIntervalSince1970
        return ((currentTime - cachedTime) > 20.minutes)
    }
}

但是,尝试创建这样的缓存:

var cache: [NSURL : CachedItem]

失败并出现错误:“对泛型类型'CachedItem'的引用需要&lt; ...&gt;”中的参数,我理解这意味着我需要做类似这样的事情:

var cache: [NSURL : CachedItem<Item>]

有什么方法可以得到我想要的东西吗?或者任何其他缓存非基于Objective-C的类的泛型类型的建议。

编辑: 对于后代,这是我在Rob回答后提出的CacheCacheItem类型。

struct Cache {
    private var cache: [String : CachedValue] = [:]
    private let queue = dispatch_queue_create("Cache Queue", DISPATCH_QUEUE_SERIAL)

    mutating func setValue(value: Any?, forType type: String) {
        dispatch_sync(queue) {
            guard let value = value else {
                return
            }

            self.cache[type] = CachedValue(value: value)
        }
    }

    func valueForType<T>(type: String) -> T? {
        var result: T?

        dispatch_sync(queue) {
            guard let cachedValue = self.cache[type] where !cachedValue.isExpired() else {
                result = .None
                return
            }

            result = cachedValue.value as? T
        }

        return result
    }
}

struct CachedValue {
    let value: Any
    private let cachedTime: NSTimeInterval

    init(value: Any) {
        self.value = value
        cachedTime = NSDate().timeIntervalSince1970
    }

    func isExpired() -> Bool {
        let currentTime = NSDate().timeIntervalSince1970
        return ((currentTime - cachedTime) > 1.minutes)
    }
}

1 个答案:

答案 0 :(得分:3)

基本上,你可以说这个缓存中的类型就是它们Decodable,这真的没有告诉你任何有用的东西,因为它们已经被解码了。留下AnyObject。如果这确实是“任何事情的缓存”,那么[NSURL: AnyObject]甚至[NSURL: Any]都是合适的。这在消费方面很难看出它的类型,但这基本上是你用来解析JSON的相同的丑陋(它基本上与AnyObject一起使用)。

我建议AnyObject很少,但在这种情况下,如果您真的想要一个大缓存(而不是每种类型的缓存,如果可能的话,这将是更好的),这可能是合适的。