我想从应用程序中的多个位置访问nscache,因为我使用它来缓存来自api端点的图像。
例如,下图中的表视图4和视图控制器6使用相同的图像,因此我不想下载它们两次。
swift - 在选项卡 View  Controller 中跨 View  Controller 访问NSCache-LMLPHP
候选解决方案:
单重态

class Cache {

    private static var sharedCache: NSCache<AnyObject, AnyObject>?
    static public func getCache () -> NSCache<AnyObject, AnyObject> {

        if sharedCache == nil {
            self.sharedCache = NSCache()
        }
        return sharedCache!
    }
}

似乎工作得不错,但“单身汉不好”所以…
将缓存存储在tabviewcontroller中
这会将视图紧密地耦合到视图控制器,因此…
以某种方式存储在appdelegate中。但这和1不一样吗?所以…
使用依赖注入。但是我们在一个tab-view控制器中,所以这和2不一样吗?
我不确定这里的策略是否正确,所以我想问是否还有其他方法可以在这里使用。
我用nscache创建了一个应用程序,并探索了一个单例解决方案。我试着使用依赖注入,但认为它没有意义。我看过堆栈溢出和文档,但是对于这种特定的情况,我没有发现潜在的解决方案。
我给出了一个很小的例子,一个我不满意的图表和测试解决方案。
没有帮助的是说nscache不正确或使用库的答案。我正在尝试使用nscache进行我自己的学习,这不是家庭作业,我想在这个应用程序结构中解决这个问题的具体实例。
问题是如何避免在这个实例中使用单例,即选项卡视图控制器中的视图控制器。

最佳答案

先上来。单身汉并不是天生的坏。它们会使你的代码很难测试,而且它们确实起到了依赖磁铁的作用。
singleton适用于工具类,例如NSFileManagerakaFileManger,即不携带状态或数据的类。
一个很好的替代方案是依赖注入,但是有了视图控制器和情节串连板,它可能会很难并且感觉非常样板。你最终把所有东西都传给了prepareForSegue
一种可能的方法是声明一个描述类缓存接口的protocol

protocol CacheProtocol: class {
    func doCacheThing()
}

class Cache: CacheProtocol {
    func doCacheThing() {
        //
    }
}

然后声明希望使用此缓存的所有对象都可以使用的protocol
protocol CacheConsumer: class {
    var cache: CacheProtocol? { get set }
    func injectCache(to object: AnyObject)
}

extension CacheConsumer {
    func injectCache(to object: AnyObject) {
        if let consumer = object as? CacheConsumer {
            consumer.cache = cache
        }
    }
}

最后在顶层创建这个缓存的具体实例。
/// Top most controller
class RootLevelViewController: UIViewController, CacheConsumer {
    var cache: CacheProtocol? = Cache()

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        injectCache(to: segue.destination)
    }

}

您可以在prepareForSegue中将缓存传递到该行。
或者可以使用细微的子分类来创建一致性。
class MyTabBarController: UITabBarController, CacheConsumer {
    var cache: CacheProtocol?
}

或者您可以使用委托方法来获取向下传播的缓存对象。
extension RootLevelViewController: UITabBarControllerDelegate {
    func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
        injectCache(to: viewController)
    }
}

现在有了一个系统,任何CacheConsumer都可以使用缓存并将其向下传递到任何其他对象。

10-08 06:27