2012-06-02 8 views

risposta

7

Stai meglio trattare NSCache come una scatola nera, per quanto è possibile.

Da Caching and Purgeable Memory (sottolineatura mia):

Quando si aggiungono elementi da una cache, è possibile specificare un valore di costo per essere associate a ciascuna coppia chiave-valore. Chiamare il metodo setTotalCostLimit: per impostare il valore massimo per la somma di tutti i costi degli oggetti memorizzati nella cache. Pertanto, quando viene aggiunto un oggetto che spinge lo totalCost sopra lo totalCostLimit, la cache potrebbe sfrattare automaticamente alcuni dei suoi oggetti per tornare al di sotto della soglia. Questo processo sgombero non è garantita, in modo da cercare di manipolare i valori cost per ottenere un comportamento specifico potrebbe pregiudicare le prestazioni della cache. Pass 0 per il cost se non hai niente di utile, o utilizza il metodo setObject:forKey:, che non richiede un costo per essere passato in

. Nota: il limite di conteggio e il limite totale di costo non sono rigorosamente applicato. Cioè, quando la cache supera uno dei suoi limiti, alcuni dei suoi oggetti potrebbero essere sfrattati immediatamente, in seguito o mai, tutto a seconda dei dettagli di implementazione della cache.

+2

E 'una buona idea per osservare l'avviso di memoria e eliminare la cache, allora? –

+1

@EvilNodoer Facendo qualche sperimentazione, ho scoperto che, mentre non risponde a 'UIApplicationDidReceiveMemoryWarningNotification', in realtà fa espellere automaticamente i suoi oggetti in situazioni di memoria insufficiente (deve essere utilizzando qualche altro meccanismo). – Rob

+0

@EvilNodoer BTW, devo ritirare il mio commento su 'NSCache' rispondere alle richieste di memoria, in quanto questo è cambiato in iOS 7. Osservando' UIApplicationDidReceiveMemoryWarningNotification' sarebbe prudente. Vedi http://stackoverflow.com/questions/19546054/nscache-crashing-when-memory-limit-is-reached-only-on-ios-7 – Rob

8

NSCache non risponde a UIApplicationDidReceiveMemoryWarningNotification, ma fa sfrattare automaticamente gli oggetti in situazioni di memoria insufficiente, ovviamente utilizzando qualche altro meccanismo.

Mentre io suggerito in precedenza osservando UIApplicationDidReceiveMemoryWarningNotification, questo non è il caso. Non è necessaria alcuna gestione speciale per situazioni di memoria insufficiente, poiché lo NSCache gestisce automaticamente questo problema.


Aggiornamento:

Come di iOS 7, l'NSCache non solo non risponde alle avvisi di memoria, ma anche non sembra in sé eliminare correttamente su pressione di memoria, o (si veda NSCache crashing when memory limit is reached (only on iOS 7)).

ho sottoclasse NSCache osservare UIApplicationDidReceiveMemoryWarningNotification, ed eliminare la cache su avviso di memoria:

@interface AutoPurgeCache : NSCache 
@end 

@implementation AutoPurgeCache 

- (id)init 
{ 
    self = [super init]; 
    if (self) { 
     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(removeAllObjects) name:UIApplicationDidReceiveMemoryWarningNotification object:nil]; 
    } 
    return self; 
} 

- (void)dealloc 
{ 
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidReceiveMemoryWarningNotification object:nil]; 

    // if not ARC, also 
    // 
    // [super dealloc]; 
} 

@end 
Problemi correlati