2015-11-08 2 views
0

J'ai un NSDictionary que j'ai mis en cache. J'ai besoin d'implémenter un setObject basé sur le temps avec horodatage. NSCache Class n'a pas d'objet setExpiry. Toute aide serait appréciée.Comment implémenter NSCache basé sur le temps avec setObject Swift 2.0

Ceci est l'extension que j'ai jusqu'à présent:

import Foundation 

extension NSCache { 

class var sharedInstance : NSCache { 
    struct Static { 
     static let instance : NSCache = NSCache() 
    } 
    return Static.instance 
} 
} 

J'ai trouvé NSCache Extension à http://nshipster.com/nscache/. Un moyen facile de mettre en œuvre avec un horodatage d'expiration?

extension NSCache { 
subscript(key: AnyObject) -> AnyObject? { 
    get { 
     return objectForKey(key) 
    } 
    set { 
     if let value: AnyObject = newValue { 
      setObject(value, forKey: key) 
     } else { 
      removeObjectForKey(key) 
     } 
    } 
} 
} 
+1

Un peu hors sujet, mais si vous essayez de créer un singleton par ce que vous avez dans l'extension en ce moment, vous devriez vérifier out [cet article] (http://krakendev.io/blog/the-right-way-to-write-a-singleton). Vous pouvez créer un singleton sur une ligne, comme ceci: 'static let sharedInstace = NSCache()'. –

+0

J'ai un JSON, dont j'ai besoin de le mettre en cache avec l'horodatage d'expiration de 1HR. Pensez-vous que mon approche est suffisante? Merci .. –

Répondre

1

Vous pouvez également utiliser une minuterie pour vider la file d'attente:

private let ExpiringCacheObjectKey = "..." 
private let ExpiringCacheDefaultTimeout: NSTimeInterval = 60 

class ExpiringCache : NSCache { 

    /// Add item to queue and manually set timeout 
    /// 
    /// - parameter obj: Object to be saved 
    /// - parameter key: Key of object to be saved 
    /// - parameter timeout: In how many seconds should the item be removed 

    func setObject(obj: AnyObject, forKey key: AnyObject, timeout: NSTimeInterval) { 
     super.setObject(obj, forKey: key) 
     NSTimer.scheduledTimerWithTimeInterval(timeout, target: self, selector: "timerExpires:", userInfo: [ExpiringCacheObjectKey : key], repeats: false) 
    } 

    // Override default `setObject` to use some default timeout interval 

    override func setObject(obj: AnyObject, forKey key: AnyObject) { 
     setObject(obj, forKey: key, timeout: ExpiringCacheDefaultTimeout) 
    } 

    // method to remove item from cache 

    func timerExpires(timer: NSTimer) { 
     removeObjectForKey(timer.userInfo![ExpiringCacheObjectKey] as! String) 
    } 
} 
+0

Merci @Rob - va l'essayer .. –

+0

Hey @Rob, je reçois une erreur potentielle, pouvez-vous s'il vous plaît aider? [Screenshot] (https://www.dropbox.com/s/d9wocj6dzex380j/Screenshot%202015-11-08%2016.09.24.png?dl=0) Voici ce que je pense que devrait être la syntaxe removeObjectForKey (timer.userInfo ! [ExpiringCacheObjectKey])? –

+0

N'ajoutez pas de minuteur pour chaque clé dans votre cache, vous devez ajouter une date d'expiration à la clé et la vérifier lorsque vous récupérez l'objet. –

2

Voici l'approche de base.

PS: Je n'ai pas testé ce code et je l'ai écrit dans l'éditeur de texte. Il peut exiger quelques ajustements en fonction de vos besoins :)

import Foundation 

protocol Cacheable: class { 
    var expiresAt : NSDate { get set } 
} 

class CacheableItem : Cacheable { 
    var expiresAt = NSDate() 
} 

extension NSCache { 

    subscript(key: AnyObject) -> Cacheable? { 
     get { 
      if let obj = objectForKey(key) as? Cacheable { 
       var now = NSDate(); 
       if now.isGreaterThanDate(obj.expiresAt) { 
        removeObjectForKey(key) 
       } 
      } 

      return objectForKey(key) as? Cacheable 
     } 
     set { 
      if let value = newValue { 
       setObject(value, forKey: key) 
      } else { 
       removeObjectForKey(key) 
      } 
     } 
    } 
} 

extension NSDate 
{ 
    func isGreaterThanDate(dateToCompare : NSDate) -> Bool 
    { 
     var isGreater = false 

     if self.compare(dateToCompare) == NSComparisonResult.OrderedDescending { 
      isGreater = true 
     } 

     return isGreater 
    } 
} 

Basé sur this Stack Overflow answer.

+0

Un grand merci! Will tester et voir comment fonctionne .. Cheers :) –

+0

@TalZion Je viens de faire une modification à la réponse, de sorte que le code compile réellement. –

+0

@TalZion J'ai modifié ma réponse. corriger l'erreur logique dans la comparaison des dates. J'espère que cela fonctionne pour vous :) – ProblemSlover