Swift NSCache Singleton

Aug 31 2020

ฉันต้องการห่อ NSCache ใน Singleton เพื่อใช้การฉีดการพึ่งพาในโค้ดของฉัน สิ่งนี้ส่งผลให้ค่อนข้างน่าเสียดายที่ในการส่งผ่านประเภทผ่านพารามิเตอร์ฟังก์ชันและฉันยังต้องการสองม็อกสำหรับความสำเร็จและความล้มเหลวเนื่องจากเป็นอินสแตนซ์ซิงเกิลตัน

ฉันคิดว่าอาจมีวิธีที่ดีกว่านี้ แต่มีความคิดเห็นที่น่าชื่นชม!

ImageCache และโปรโตคอล

protocol ImageCacheProtocol {
    static var shared: Self { get }
    func getCache() -> NSCache<AnyObject, UIImage>
}

final class ImageCache: ImageCacheProtocol {
    var cache: NSCache<AnyObject, UIImage> = NSCache<AnyObject, UIImage>()

    public static let shared = ImageCache()
    private init() {}
    
    func getCache() -> NSCache<AnyObject, UIImage> {
        return cache
    }
}

MockImageCache & MockImageCacheFailure

final class MockImageCache: ImageCacheProtocol {
    var cache: NSCache<AnyObject, UIImage> = MockNSCache(shouldReturnImage: true)

    public static let shared = MockImageCache()
    private init() {}

    func getCache() -> NSCache<AnyObject, UIImage> {
        return cache
    }
}


final class MockImageCacheFailure: ImageCacheProtocol {
    var cache: NSCache<AnyObject, UIImage> = MockNSCache(shouldReturnImage: false)

    public static let shared = MockImageCacheFailure()
    private init() {}

    func getCache() -> NSCache<AnyObject, UIImage> {
        return cache
    }
}

การสร้างอินสแตนซ์โมเดลมุมมองของฉัน (ตัวอย่างข้อมูล)

class ViewModel<U: ImageCacheProtocol> {

    private var cache: U.Type
    init<T: NetworkManagerProtocol>(networkManager: T, data: DisplayContent, imageCache: U.Type) {
        self.networkManager = AnyNetworkManager(manager: networkManager)
        
        cache = imageCache

คำตอบ

WishIHadThreeGuns Sep 02 2020 at 14:29

ใช่นี่ไม่ใช่วิธีที่ยอมรับได้ วิธีแก้ปัญหาของฉันคือการไม่ใช้Selfและเน้นที่แชร์แทน

นั่นคือ:

protocol ImageCacheProtocol {
    func getCache() -> NSCache<AnyObject, UIImage>
}

final class ImageCache: ImageCacheProtocol {
    var cache: NSCache<AnyObject, UIImage> = NSCache<AnyObject, UIImage>()
    static var shared = ImageCache()
    
    private init() {}
    
    func getCache() -> NSCache<AnyObject, UIImage> {
        return cache
    }
}

จากนั้นล้อเลียนสามารถเปลี่ยนแปลงได้:

final class MockImageCache: ImageCacheProtocol {
    var cache: NSCache<AnyObject, UIImage> = MockNSCache(shouldReturnImage: true)
    public static var shared: ImageCacheProtocol! = MockImageCache()
    func getCache() -> NSCache<AnyObject, UIImage> {
        return cache
    }
}