Wir verwenden NSCache für UIImages in unserer App. Dies funktioniert auf iOS-Versionen kleiner als 7. Wenn eine Speicherwarnung auftritt, gibt NSCache Objekte wie vorgesehen frei. Unter iOS 7 stürzt unsere App jedoch kurz nach der ersten Speicherwarnung ab. Es sieht also so aus, als würden Objekte, die mit NSCache gespeichert wurden, nie freigegeben, aber der Cache wächst, bis die App abstürzt. Profiling mit Instrumenten bestätigt diesen Verdacht.NSCache stürzt ab, wenn das Speicherlimit erreicht ist (nur unter iOS 7)
Hatte jemand anderes dieses Problem und haben Sie einen Workaround gefunden oder haben Sie bereits einen Fehler gefunden?
Es sieht aus wie die Jungs das gleiche Problem hatte: http://www.photosmithapp.com/index.php/2013/10/photosmith-3-0-2-photo-caching-and-ios-7/
ich eine kleine Beispielanwendung erstellt, das Problem zu veranschaulichen. Wenn eine Taste gedrückt wird, wird die Methode -(IBAction)fillCache:(id)sender
aufgerufen. Von nun an ruft ein Timer alle 100 ms -(void)addImageToCache:(id)sender
auf. In dieser Methode wird ein UIImage generiert und in den Cache geschrieben.
Auf dem iPad Mini mit iOS 7.0.3 und seinem 512 MB Speicher stürzt es nach ~ 350 Iterationen ab.
Auf dem iPad 2 mit iOS 5 und auch 512 MB Speicher stürzt es irgendwann ab, aber erst nach mindestens 3000 Iterationen. Instruments zeigt, dass die Anzahl der UIImage-Instanzen bei jeder Speicherwarnung abnimmt. Dies ist unter iOS 7 nicht der Fall.
- (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];
}
}
diese gesund und fein scheint ... Ich frage mich, ob es ein wenig plump ist Könntest du ... stattdessen totalCostLimit oder countLimit reduzieren? –
@GradyPlayer Einverstanden. Ich mag deine Idee, aber ich war mir nicht sicher, wie du sicher sein könntest, dass das Ändern der Limits, wie du es vorgeschlagen hast, ausreichen würde, um die App in eine stabile Situation zu bringen. Man könnte auch vorab vernünftige Grenzen setzen und verhindern, dass der Speicheralarm überhaupt auftritt.Aber wenn Sie das tun und immer noch Gedächtniswarnungen erhalten, dann könnte dieser unberechenbare Ansatz ein Bollwerk gegen katastrophales Versagen sein. – Rob
Sie haben wahrscheinlich recht, ich weiß nicht, ob es auch ein oder zwei Drehungen durch den Runloop braucht ... Ich denke, Sie sollten nichts darin haben, das Sie später nicht neu erstellen können. –