วิธีใช้ NSCache


121

ใครช่วยยกตัวอย่างวิธีใช้NSCacheแคชสตริงได้ไหม หรือใครมีลิงค์คำอธิบายดีๆ? หาไม่เจอ ..


7
แม้จะเห็นโกโก้จำนวนมาก แต่ฉันไม่เคยได้ยิน NSCache มาก่อน คำถามที่ดี!
Nektarios

ฉันสร้าง NSCache เวอร์ชันที่ทำซ้ำได้ที่นี่ อย่าลังเลที่จะมีส่วนร่วม: github.com/gregkrsak/GKCache
Greg M. Krsak

คำตอบ:


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 จัดสรร] init]
Thizzer

17
ไม่ใช่แคชถาวรบนดิสก์ มันอยู่ในหน่วยความจำเท่านั้นใช่มันจะถูกทำลายทุกครั้งที่แอปของคุณหยุดทำงาน
Jonathan Grynspan

แคชนี้ได้รับการดูแลเมื่อหลังจากที่แอปพลิเคชันเข้าสู่ backgruond หรือไม่ (เช่นหลังapplicationDidEnterBackground)
barfoon

หากแอปพลิเคชันไม่ถูกยกเลิกและNSCacheไม่ได้ทำการจัดสรรอ็อบเจ็กต์ใช่มันจะยังคงอยู่ในหน่วยความจำ อย่างไรก็ตามเนื้อหาอาจยังคงอยู่ภายใต้การคัดแยก
Jonathan Grynspan

3
ไม่คำยืนยันยืนยันว่าบางสิ่งเป็นจริงกล่าวคือคาดว่าข้อความภายในจะเป็นจริง เรายืนยันว่าการกำหนดวัตถุและ / หรือการสร้างประสบความสำเร็จ
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"];

3
ใช่. บันทึก: [imagesDictionary setObject: imageData forKey: @ "KEY"]; ดึงข้อมูล: NSData * imageData = [imagesCache objectForKey: @ "KEY"];
Gabriel.Massana

2
บันทึกข้อมูลลงใน chache: [imagesCache setObject: imageData forKey: @ "KEY"];
kas-kad

1
ฉันเพิ่งแก้ไขโพสต์ที่เปลี่ยนไป: imagesDictionary สำหรับ imagesCache Thx
Gabriel.Massana

ตัวอย่างที่รวดเร็วเทียบเท่า?
Jasper

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
คุณรู้วิธีใช้สิ่งนี้ใน swift 3 หรือไม่?
Andy

3
สิ่งนี้ควรใช้งานได้: class Cache: NSCache<AnyObject, AnyObject> { static let shared = NSCache<AnyObject, AnyObject>() private override init() { super.init() } }
AmitaiB

6

ตัวอย่างไฟล์ Project Add 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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.