2011-09-05 9 views
9

Chcę przechowywać różne obiekty w NSCache i automatycznie je usuwać po ostrzeżeniu o pamięci. Napisałem następującą implementację NSDiscardableContent, której używam do zawijania instancji umieszczanych w wartościach w NSCache.Jak używać NSCache z ogólną implementacją NSDiscardableContent

Ale nigdy nie widzę, aby zostały usunięte z pamięci podręcznej, gdy uruchomię funkcję "Symuluj ostrzeżenie o pamięci". Czy coś jest nie tak z moją implementacją NSDiscardableContent? Czy muszę zrobić coś innego, aby pamięć podręczna upuściła wartości, gdy pojawi się ostrzeżenie o pamięci?

/** @brief generic implementation of the NSDiscardableContent for storing objects in an NSCache */ 
@interface GenericDiscardableObject : NSObject<NSDiscardableContent> 
@property (nonatomic, retain) id object; 
@property (nonatomic) NSUInteger accessCount; 
+ (GenericDiscardableObject *)discardableObject:(id)ob; 
@end 

@implementation GenericDiscardableObject 
@synthesize object, accessCount; 

+ (GenericDiscardableObject *)discardableObject:(id)ob { 
    GenericDiscardableObject *discardable = [[GenericDiscardableObject alloc] init]; 
    discardable.object = ob; 
    discardable.accessCount = 0u; 
    return [discardable autorelease]; 
} 

- (void)dealloc { 
    self.object = nil; 
    [super dealloc]; 
} 

- (BOOL)beginContentAccess { 
    if (!self.object) 
     return NO; 
    self.accessCount = self.accessCount + 1; 
    return YES; 
} 

- (void)endContentAccess { 
    if (self.accessCount) 
     self.accessCount = self.accessCount - 1; 
} 

- (void)discardContentIfPossible { 
    if (!self.accessCount) 
     self.object = nil; 
} 

- (BOOL)isContentDiscarded { 
    return self.object == nil; 
} 
@end 
+0

To nie jest odpowiedź, ale na ogół złą praktyką jest używanie ustawienia w metodzie dealloc - nie wiesz, czy ktoś słucha KVO itd. Po prostu wykonaj polecenie "[release release]' :) – deanWombourne

+0

@deanWombourne There nie powinno być nikim, kto nasłuchuje na obiekcie w - (void) dealloc, ponieważ obiekt nie jest już zachowywany. Czy rozumiem coś nie tak? Pytam tylko dlatego, że ja też wolę właściwości dealokowania ... – radiospiel

+0

Po prostu dlatego, że nie jest już dłużej zachowywany, nie oznacza, że ​​nikt nie słucha;) Apple podejmuje temat: http://developer.apple.com/library/ mac/# documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmPractical.html i ciekawsza rozmowa tutaj: http://www.cocoabuilder.com/archive/cocoa/242096-avoiding-kvo-in-dealloc.html – deanWombourne

Odpowiedz

8

Z tego co wiem, domyślne zachowanie NSCache polega na odrzucaniu obiektów, gdy pojawi się ostrzeżenie o pamięci.

Możesz więc po prostu przechowywać swoje rzeczy "nago" w pamięci podręcznej, tak jakby były one NSDictionary, i zostaną wyczyszczone, gdy pamięć się zacieśni. Nie musisz owijać ich w przedmioty, które można odrzucić, ani robić nic innego. Na przykład.

[myCache setObject:foo forKey:@"bar"]; // foo will be released if memory runs low 

To nie bardzo wynika z dokumentacji, ale o ile mogę powiedzieć, celem protokołu <NSDiscardableContent> zawartości jest za realizację bardziej złożonych zachowań której obiekt może zwolnić podskładniki gdy pamięć jest niski, bez konieczności zwalniania samo.

Powiązane problemy