środa, 20 listopada 2013

NSCache - dlaczego by nie?

Zwykle programiści używają podręcznego cache przy użyciu nsdictionary. Chciałbym w dzisiejszym poście zwrócić uwage na coś czym bez problemowo możemy zastąpić nsdictionary a co oferuje nam SDK, niestety programiści Objective C, zbyt rzadko sięgają moim zdaniem po NSCache.




NSCache - jak dokumentacja podaje :)

#import <Foundation/NSObject.h>

@class NSString;
@protocol NSCacheDelegate;

NS_CLASS_AVAILABLE(10_6, 4_0)
@interface NSCache : NSObject {
@private
    id _delegate;
    void *_private[5];
    void *_reserved;
}

- (void)setName:(NSString *)n;
- (NSString *)name;

- (void)setDelegate:(id <NSCacheDelegate>)d;
- (id <NSCacheDelegate>)delegate;

- (id)objectForKey:(id)key;
- (void)setObject:(id)obj forKey:(id)key; // 0 cost
- (void)setObject:(id)obj forKey:(id)key cost:(NSUInteger)g;
- (void)removeObjectForKey:(id)key;

- (void)removeAllObjects;

- (void)setTotalCostLimit:(NSUInteger)lim;
- (NSUInteger)totalCostLimit; // limits are imprecise/not strict

- (void)setCountLimit:(NSUInteger)lim;
- (NSUInteger)countLimit; // limits are imprecise/not strict

- (BOOL)evictsObjectsWithDiscardedContent;
- (void)setEvictsObjectsWithDiscardedContent:(BOOL)b;

@end

@protocol NSCacheDelegate <NSObject>
@optional
- (void)cache:(NSCache *)cache willEvictObject:(id)obj;
@end


to co najwazniejsze czyli wrzucenia obiektu do cache:

- (void)setObject:(id)obj forKey:(id)key; // 0 cost
- (void)setObject:(id)obj forKey:(id)key cost:(NSUInteger)g;

Druga metoda jest o tyle ciekawsza, że pozwala na określenie wagi obiektu. Jeżeli wrzucamy obiekty tego samego typu np. UIImage możemy dla każdego z osobna okreslić koszt zajmowania w cache'u. 

przykład:

[self.cache setObject:image forKey:key cost:image.size.height * image.size.width * image.scale];

Oczywiście warto wtedy ustawić totalCostLimit, dzięki czemu będziemy mieli automatyczne usuwanie obiektów z cache, jezeli przekroczymy maksymalny limit. Według dokumentacji nie ma tutaj określonej kolejności zwalaniania obiektów z pamięci. Jezeli nie chcemy korzystać z kosztu wtedy cost = 0, bądź korzystamy z pierwszej metody.

Analogicznie możemy ustalić limit obiektów w cache, przy użyciu setCountLimit. 

O tym, że obiekt został zwolniony poinformuje nas delegate (oczywiście należy go ustawić dla obiektu NSCache) poprzez metodę: 

- (void)cache:(NSCache *)cache willEvictObject:(id)obj;

Wyciąganie obiektu, oraz reszta metod chyba nie jest konieczna do opisywania, więc na tym zakończę. Zależało mi żeby dosyć sprawnie przybliżyć i zachęcić do korzystania z NSCache. 

Pozdrawiam. 





0 komentarze:

Prześlij komentarz