Usiamo NSCache per UIImages nella nostra app. Funziona perfettamente su versioni iOS inferiori a 7. Quando si verifica un avviso di memoria, NSCache rilascia oggetti come previsto. Tuttavia, su iOS 7, la nostra app si blocca poco dopo il primo avviso di memoria. Sembra quindi che gli oggetti archiviati con NSCache non vengano mai rilasciati, ma la cache sta crescendo fino a quando l'app non si arresta. La profilazione con strumenti conferma questo sospetto.Arresto anomalo di NSCache quando viene raggiunto il limite di memoria (solo su iOS 7)
Qualcun altro ha riscontrato questo problema e ha trovato una soluzione alternativa o ha già tracciato un bug?
Sembra che quei ragazzi avevano lo stesso problema: http://www.photosmithapp.com/index.php/2013/10/photosmith-3-0-2-photo-caching-and-ios-7/
ho creato una piccola applicazione di esempio per illustrare il problema. Quando viene premuto un pulsante, viene chiamato il metodo -(IBAction)fillCache:(id)sender
. Da quel momento in poi, un timer chiama -(void)addImageToCache:(id)sender
ogni 100 ms. In questo metodo, un UIImage viene generato e scritto nella cache.
Sull'iPad Mini con iOS 7.0.3 e la sua memoria da 512 MB, si blocca dopo ~ 350 iterazioni.
Sull'iPad 2 con iOS 5 e anche 512 MB di memoria, si arresta anche a un certo punto, ma solo dopo almeno 3000 iterazioni. Gli strumenti mostrano che il numero di istanze UIImage diminuisce ogni volta che si verifica un avviso di memoria. Questo non è il caso su iOS 7.
- (IBAction)fillCache:(id)sender
{
[NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(addImageToCache:) userInfo:nil repeats:YES];
}
- (void)addImageToCache:(id)sender
{
@autoreleasepool {
CGRect rect = CGRectMake(0, 0, 500, 500);
UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSString *poolKey = [NSString stringWithFormat:@"junk_%d", count++];
[self.cache setObject:image forKey:poolKey];
}
}
questo sembra sano e bene ... mi chiedo se è un po 'la mano pesante , potresti ... ridurre invece il valore TotalCostLimit o CountLimit? –
@GradyPlayer Concordato. Mi piace la tua idea, ma non ero sicuro di come potresti essere sicuro che modificare i limiti come hai suggerito sarebbe sufficiente per ripristinare l'app in una situazione stabile. Si potrebbero anche impostare limiti ragionevoli in anticipo e potrebbe prevenire l'allarme memoria che si verifica in primo luogo.Ma se lo fai e ricevi ancora avvertimenti sulla memoria, allora questo approccio pesante potrebbe essere un baluardo contro un fallimento catastrofico. – Rob
probabilmente hai ragione, non so se ci vuole un giro o due attraverso il runloop ... Suppongo che non dovresti avere niente lì dentro che non puoi ricreare più tardi. –