Cara menggunakan NSCache

121

Dapatkah seseorang memberikan contoh tentang cara menggunakan NSCachecache string? Atau ada yang punya link ke penjelasan yang bagus? Sepertinya saya tidak dapat menemukan ..

Thizzer
sumber
7
Meskipun melihat sejumlah besar Cocoa, saya belum pernah mendengar tentang NSCache. Pertanyaan bagus!
Nektarios
Saya membuat versi NSCache yang dapat diulang, di sini. Jangan ragu untuk berkontribusi: github.com/gregkrsak/GKCache
Greg M. Krsak

Jawaban:

134

Anda menggunakannya dengan cara yang sama seperti Anda menggunakannya NSMutableDictionary. Perbedaannya adalah ketika NSCachemendeteksi tekanan memori yang berlebihan (yaitu menyimpan terlalu banyak nilai), ia akan melepaskan beberapa nilai tersebut untuk memberi ruang.

Jika Anda dapat membuat ulang nilai-nilai tersebut saat runtime (dengan mengunduh dari Internet, dengan melakukan penghitungan, apa pun) maka NSCachemungkin sesuai dengan kebutuhan Anda. Jika data tidak dapat dibuat ulang (misalnya, input pengguna, sensitif waktu, dll.) Maka Anda tidak boleh menyimpannya diNSCache karena akan dihancurkan di sana.

Contoh, tidak memperhitungkan keamanan benang:

// 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];
}
Jonathan Grynspan
sumber
1
bagaimana cara membuat instance objek NSCache? Sepertinya saya kehilangan semua info yang di-cache setiap kali saya menjalankan aplikasi. Saya menggunakan; [[NSCache alokasi] init]
Thizzer
17
Ini bukan cache permanen pada disk. Ini hanya dalam memori, jadi ya, itu akan dimusnahkan setiap kali aplikasi Anda berhenti berjalan.
Jonathan Grynspan
Apakah cache ini dipertahankan setelah aplikasi memasuki backgruond? (yaitu setelah applicationDidEnterBackground)
barfoon
Jika aplikasi tidak dihentikan dan NSCacheobjek tidak dibatalkan alokasinya, maka ya, itu akan tetap ada di memori. Namun, isinya mungkin masih dapat disingkirkan.
Jonathan Grynspan
3
Tidak. Suatu pernyataan menegaskan bahwa sesuatu itu benar, yaitu pernyataan di dalamnya diharapkan benar. Kami menegaskan bahwa penugasan objek dan / atau pembuatan berhasil.
Jonathan Grynspan
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"];
Gabriel.Massana
sumber
3
Iya. Simpan: [imagesDictionary setObject: imageData forKey: @ "KEY"]; ambil: NSData * imageData = [imagesCache objectForKey: @ "KEY"];
Gabriel.Massana
2
menyimpan data ke chache: [imagesCache setObject: imageData forKey: @ "KEY"];
kas-kad
1
Saya baru saja mengedit posting yang diubah: imagesDictionary for imagesCache. Thx
Gabriel. Massana
Contoh cepat yang setara?
Jasper
9

Contoh kode untuk menyimpan string menggunakan NSCache di 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"

Untuk membuat satu instance NSCache di seluruh aplikasi (tunggal), Anda dapat dengan mudah memperluas NSCache untuk menambahkan properti sharedInstance. Letakkan saja kode berikut di file bernama sesuatu seperti NSCache + Singleton.swift:

import Foundation

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

Anda kemudian dapat menggunakan cache di mana saja di aplikasi:

NSCache.sharedInstance.setObject("String for key 2", forKey: "Key2")
var result2 = NSCache.sharedInstance.objectForKey("Key2") as String
println(result2) // Prints "String for key 2"
PointZeroTwo
sumber
3
apakah Anda tahu cara menerapkan ini di swift 3?
Andy
3
Ini harus bekerja: class Cache: NSCache<AnyObject, AnyObject> { static let shared = NSCache<AnyObject, AnyObject>() private override init() { super.init() } }
AmitaiB
6

contoh Proyek Tambahkan file CacheController.h dan .m dari proyek contoh ke proyek Anda. Di kelas tempat Anda ingin menyimpan data, letakkan kode di bawah ini.

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

Anda dapat mengatur objek apa pun menggunakan ini

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

untuk mundur

Penting: Kelas NSCache menggabungkan berbagai kebijakan penghapusan otomatis. jika Anda ingin menyimpan data secara permanen atau Anda ingin menghapus data cache dalam waktu tertentu lihat jawaban ini .

Ajumal
sumber
1

Bukankah objek yang di-cache harus menerapkan protokol NSDiscardableContent?

Dari referensi kelas NSCache: Tipe data umum yang disimpan dalam objek NSCache adalah objek yang mengimplementasikan protokol NSDiscardableContent. Menyimpan objek jenis ini dalam cache memiliki keuntungan, karena isinya dapat dibuang saat tidak diperlukan lagi, sehingga menghemat memori. Secara default, objek NSDiscardableContent di cache secara otomatis dihapus dari cache jika kontennya dibuang, meskipun kebijakan penghapusan otomatis ini dapat diubah. Jika objek NSDiscardableContent dimasukkan ke dalam cache, cache akan memanggil discardContentIfPossible padanya saat dihapus.

Phoenix
sumber
1
Anda dapat menerapkan protokol NSDiscardableContent tetapi ini tidak diperlukan. Sepertinya NSDiscardableContent selalu dihapus dari NSCache jika tidak ada lagi referensi. Objek selain objek NSDiscardableContent disimpan di NSCache sampai ada 'memori ketat' dan NSCache akan dihapus.
Thizzer