Як користуватися NSCache


121

Чи може хтось навести приклад того, як використовувати NSCacheдля кешування рядка? Або хтось має посилання на гарне пояснення? Я не можу знайти жодного ..


7
Незважаючи на те, що я бачив величезну кількість какао, я ніколи не чув про NSCache. Гарне питання!
Нектаріос

Тут я створив ітерабельну версію NSCache. Не соромтеся робити свій внесок у це: github.com/gregkrsak/GKCache
Грег М. Крсак

Відповіді:


134

Ви використовуєте його так само, як і ви NSMutableDictionary. Різниця полягає в тому, що при NSCacheвиявленні надмірного тиску пам’яті (тобто це кешування занадто багато значень) він випустить деякі з цих значень, щоб звільнити місце.

Якщо ви можете відтворити ці значення під час виконання (завантажуючи з Інтернету, роблячи розрахунки, що завгодно), то це NSCacheможе відповідати вашим потребам. Якщо дані не вдасться відтворити (наприклад, це введення користувача, воно чутливе до часу тощо), то вам не слід зберігати їх у файлі, NSCacheоскільки він буде знищений там.

Приклад, не враховуючи безпеку потоку:

// Your cache should have a lifetime beyond the method or handful of methods
// that use it. For example, you could make it a field of your application
// delegate, or of your view controller, or something like that. Up to you.
NSCache *myCache = ...;
NSAssert(myCache != nil, @"cache object is missing");

// Try to get the existing object out of the cache, if it's there.
Widget *myWidget = [myCache objectForKey: @"Important Widget"];
if (!myWidget) {
    // It's not in the cache yet, or has been removed. We have to
    // create it. Presumably, creation is an expensive operation,
    // which is why we cache the results. If creation is cheap, we
    // probably don't need to bother caching it. That's a design
    // decision you'll have to make yourself.
    myWidget = [[[Widget alloc] initExpensively] autorelease];

    // Put it in the cache. It will stay there as long as the OS
    // has room for it. It may be removed at any time, however,
    // at which point we'll have to create it again on next use.
    [myCache setObject: myWidget forKey: @"Important Widget"];
}

// myWidget should exist now either way. Use it here.
if (myWidget) {
    [myWidget runOrWhatever];
}

1
як інстанціювати об'єкт NSCache? Я, здається, втрачаю всю кешовану інформацію щоразу, коли запускаю додаток. Я використовую; [[NSCache alloc] init]
Thizzer

17
Це не постійний кеш на диску. Це лише в пам'яті, так що так, воно руйнується кожного разу, коли ваша програма перестає працювати.
Джонатан Грінспан

Чи підтримується цей кеш-пам'ять, коли програма входить у бекгрунд? (тобто після applicationDidEnterBackground)
барфун

Якщо додаток не буде припинено і NSCacheоб'єкт не розміщений, то так, він залишиться в пам'яті. Однак його вміст все ще може бути предметом вилучення.
Джонатан Грінспан

3
Ні. Затвердження стверджує, що щось є правдивим, тобто, що твердження в межах очікується істинним. Ми стверджуємо, що призначення та / або створення об'єкта було успішним.
Джонатан Гринспан

19
@implementation ViewController
{    
    NSCache *imagesCache;    
}


- (void)viewDidLoad
{    
    imagesCache = [[NSCache alloc] init];
}


// How to save and retrieve NSData into NSCache
NSData *imageData = [imagesCache objectForKey:@"KEY"];
[imagesCache setObject:imageData forKey:@"KEY"];

3
Так. Зберегти: [imagesDictionary setObject: imageData forKey: @ "KEY"]; отримати: NSData * imageData = [imagesCache objectForKey: @ "KEY"];
Габріель.Массана

2
зберегти дані в чаш: [imagesCache setObject: imageData forKey: @ "KEY"];
kas-kad

1
Я щойно відредагував повідомлення змінив: imagesDictionary for imagesCache. Thx
Габріель.Массана

Еквівалентний швидкий приклад?
Джаспер

9

Приклад коду для кешування рядка за допомогою NSCache у Swift:

var cache = NSCache()
cache.setObject("String for key 1", forKey: "Key1")
var result = cache.objectForKey("Key1") as String
println(result) // Prints "String for key 1"

Щоб створити єдиний екземпляр NSCache для сімейства додатків (одиночний), ви можете легко розширити NSCache, щоб додати властивість sharedInstance. Просто введіть такий код у файл, який називається на зразок NSCache + Singleton.swift:

import Foundation

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

Потім ви можете використовувати кеш у будь-якій точці програми:

NSCache.sharedInstance.setObject("String for key 2", forKey: "Key2")
var result2 = NSCache.sharedInstance.objectForKey("Key2") as String
println(result2) // Prints "String for key 2"

3
чи знаєте ви, як це реалізувати у швидкій 3?
Енді

3
Це має спрацювати: class Cache: NSCache<AnyObject, AnyObject> { static let shared = NSCache<AnyObject, AnyObject>() private override init() { super.init() } }
AmitaiB

6

зразок проекту Додайте файл CacheController.h та .m із зразкового проекту до свого проекту. У класі, де ви хочете кешувати дані, введіть наведений нижче код.

[[CacheController storeInstance] setCache:@"object" forKey:@"objectforkey" ];

ви можете встановити будь-який об’єкт за допомогою цього

[[CacheController storeInstance] getCacheForKey:@"objectforkey" ];

відновити

Важливо: Клас NSCache містить різні політики автоматичного видалення. якщо ви хочете, щоб дані кешувались постійно, або ви хочете видалити кешовані дані за певний час, перегляньте цю відповідь .


1

Чи не повинні кешовані об'єкти реалізовувати протокол NSDiscardableContent?

З посилання на клас NSCache: Загальний тип даних, що зберігається в об'єктах NSCache, є об'єктом, який реалізує протокол NSDiscardableContent. Зберігання цього типу об’єктів у кеші має переваги, оскільки його вміст можна відкинути, коли він більше не потрібен, тим самим економлячи пам’ять. За замовчуванням об’єкти NSDiscardableContent в кеші автоматично видаляються з кешу, якщо їх вміст відкидається, хоча цю політику автоматичного видалення можна змінити. Якщо об’єкт NSDiscardableContent поміщений у кеш, кеш викликає discardContentIfPossible при його видаленні.


1
Ви можете реалізувати протокол NSDiscardableContent, але це не потрібно. Як здається, NSDiscardableContent завжди видаляється з NSCache, коли немає більше посилань. Об'єкти, відмінні від об'єкта NSDiscardableContent, зберігаються в NSCache до тих пір, поки "пам'ять не є щільною" і NSCache не буде очищений.
Thizzer
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.