Может кто-нибудь привести пример того, как использовать NSCacheдля кеширования строки? Или у кого-нибудь есть ссылка на хорошее объяснение? Кажется, я не могу найти ...
Несмотря на то, что я видел огромное количество какао, я никогда не слышал о NSCache. Хороший вопрос!
Nektarios
Я создал итеративную версию 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];}
как создать экземпляр объекта NSCache? Кажется, я теряю всю кешированную информацию каждый раз, когда запускаю приложение. Я использую; [[NSCache alloc] init]
Thizzer
17
Это не постоянный кеш на диске. Он находится только в памяти, поэтому да, он уничтожается каждый раз, когда ваше приложение перестает работать.
Джонатан Гринспан
Поддерживается ли этот кеш после того, как приложение переходит в фоновый режим? (т.е. после applicationDidEnterBackground)
barfoon
Если приложение не завершено и NSCacheобъект не освобожден, то да, он останется в памяти. Однако его содержимое может быть удалено.
Джонатан Гринспан
3
Нет. Утверждение утверждает, что что-то истинно, т. Е. Что утверждение внутри должно быть истинным. Мы утверждаем, что назначение и / или создание объекта было успешным.
Джонатан Гринспан
19
@implementationViewController{NSCache*imagesCache;}-(void)viewDidLoad
{
imagesCache =[[NSCache alloc] init];}// How to save and retrieve NSData into NSCacheNSData*imageData =[imagesCache objectForKey:@"KEY"];[imagesCache setObject:imageData forKey:@"KEY"];
сохранить данные в chache: [imagesCache setObject: imageData forKey: @ "KEY"];
kas-kad
1
Я только что отредактировал сообщение изменено: imagesDictionary для imagesCache. Thx
Gabriel.Massana
Эквивалентный быстрый пример?
Джаспер
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:
importFoundation
extension NSCache{class var sharedInstance :NSCache{structStatic{static let instance :NSCache=NSCache()}returnStatic.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"
Это должно работать: class Cache: NSCache<AnyObject, AnyObject> { static let shared = NSCache<AnyObject, AnyObject>() private override init() { super.init() } }
AmitaiB
6
образец проекта
Добавьте файл CacheController.h и .m из образца проекта в свой проект. В классе, в котором вы хотите кэшировать данные, поместите приведенный ниже код.
Важно: класс NSCache включает в себя различные политики автоматического удаления. если вы хотите кэшировать данные на постоянной основе или хотите удалить кешированные данные в определенное время, см. этот ответ .
Разве кэшированные объекты не должны реализовывать протокол NSDiscardableContent?
Из справочника по классу NSCache: Общий тип данных, хранящийся в объектах NSCache, - это объект, реализующий протокол NSDiscardableContent. Хранение этого типа объекта в кэше имеет преимущества, потому что его содержимое может быть удалено, когда оно больше не нужно, тем самым экономя память. По умолчанию объекты NSDiscardableContent в кэше автоматически удаляются из кеша, если их содержимое отбрасывается, хотя эту политику автоматического удаления можно изменить. Если объект NSDiscardableContent помещается в кеш, кеш вызывает для него discardContentIfPossible после его удаления.
Вы можете реализовать протокол NSDiscardableContent, но это не обязательно. Кажется, что NSDiscardableContent всегда удаляется из NSCache, когда больше нет ссылок. Объекты, отличные от объекта NSDiscardableContent, хранятся в NSCache до тех пор, пока не будет «недостаточно памяти» и NSCache не будет очищен.
Ответы:
Вы используете его так же, как и раньше
NSMutableDictionary
. Разница в том, что приNSCache
обнаружении чрезмерной нагрузки на память (т. Е. Кэширование слишком большого количества значений) он освобождает некоторые из этих значений, чтобы освободить место.Если вы можете воссоздать эти значения во время выполнения (путем загрузки из Интернета, выполнения расчетов и т. Д.), Это
NSCache
может удовлетворить ваши потребности. Если данные не могут быть воссозданы (например, это пользовательский ввод, они чувствительны ко времени и т. Д.), Вы не должны хранить их в папке,NSCache
потому что они будут там уничтожены.Пример без учета потоковой безопасности:
источник
applicationDidEnterBackground
)NSCache
объект не освобожден, то да, он останется в памяти. Однако его содержимое может быть удалено.источник
Пример кода для кеширования строки с использованием NSCache в Swift:
Чтобы создать единый экземпляр NSCache для всего приложения (синглтон), вы можете легко расширить NSCache, добавив свойство sharedInstance. Просто поместите следующий код в файл под названием NSCache + Singleton.swift:
Затем вы можете использовать кеш в любом месте приложения:
источник
class Cache: NSCache<AnyObject, AnyObject> { static let shared = NSCache<AnyObject, AnyObject>() private override init() { super.init() } }
образец проекта Добавьте файл CacheController.h и .m из образца проекта в свой проект. В классе, в котором вы хотите кэшировать данные, поместите приведенный ниже код.
вы можете установить любой объект с помощью этого
извлечь
Важно: класс NSCache включает в себя различные политики автоматического удаления. если вы хотите кэшировать данные на постоянной основе или хотите удалить кешированные данные в определенное время, см. этот ответ .
источник
Разве кэшированные объекты не должны реализовывать протокол NSDiscardableContent?
Из справочника по классу NSCache: Общий тип данных, хранящийся в объектах NSCache, - это объект, реализующий протокол NSDiscardableContent. Хранение этого типа объекта в кэше имеет преимущества, потому что его содержимое может быть удалено, когда оно больше не нужно, тем самым экономя память. По умолчанию объекты NSDiscardableContent в кэше автоматически удаляются из кеша, если их содержимое отбрасывается, хотя эту политику автоматического удаления можно изменить. Если объект NSDiscardableContent помещается в кеш, кеш вызывает для него discardContentIfPossible после его удаления.
источник