在标签视图控制器中跨视图控制器访问NSCache

时间:2019-04-02 09:02:14

标签: swift

我想从我的APP的多个位置访问NSCache,因为我正在使用它来缓存来自API端点的图像。

例如,下图中的表格视图4和视图控制器6使用相同的图像,因此我不想两次下载它们。

enter image description here

候选解决方案:

  1. 单人

    class Cache {  
    
        private static var sharedCache: NSCache<AnyObject, AnyObject>?        
        static public func getCache () -> NSCache<AnyObject, AnyObject> {
    
            if sharedCache == nil {
                self.sharedCache = NSCache()
            }
            return sharedCache!
        } 
    }
    

似乎工作正常,但“单件邮件不好”,所以...

  1. 将缓存存储在TabViewController中

这会将视图紧密耦合到视图控制器,因此...

  1. 以某种方式存储在AppDelegate中。但这不等于1吗?所以...

  2. 使用依赖项注入。但是我们在选项卡视图控制器中,所以这与2不同吗?

我不确定这里是否采用正确的策略,因此请问是否还有其他方法可以使用。

我所做的:使用NSCache创建带有示例的应用程序,并探索了单例解决方案。香港专业教育学院试图使用依赖注入,但认为这没有任何意义。我查看了Stack溢出和文档,但是在这种特定情况下,我发现没有潜在的溶剂。

我给的内容一个最小的示例,其中包含我不满意的图表和经过测试的解决方案。

没有帮助的是回答说NSCache不正确或正在使用库。我正在尝试使用NSCache进行自己的学习,这不是家庭作业,我想在此App结构中解决此问题的此特定实例。

问题是什么:如何避免在这种情况下使用选项卡视图控制器中的视图控制器。

1 个答案:

答案 0 :(得分:2)

首先。单身人士并非天生就坏。它们会使您的代码难以测试,并且确实起到了依赖磁铁的作用。

Singletons适用于NSFileManagerFileManger等工具类,即不携带状态或数据的类。

一个很好的选择是依赖注入,但是使用视图控制器和情节提要,可能会很难并且感觉很简单。您最终将所有内容传递到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都可以使用缓存并将其下坡传递给任何其他对象。

相关问题