Ich bin neu in ARC, aber verstehe, wie es funktioniert, und ich versuche es aus. Ich bin auf iOS, also ist Speicher ein ernstes Anliegen.Wie erzwinge Release auf iOS
Ich habe eine MyObject-Klasse, die viele große Daten enthält. Ich möchte es freigeben und einen neuen Datensatz laden.
MyObject *object;
object = [[MyObject alloc] initWithData:folder1]; // load data from folder1
// later...
object = [[MyObject alloc] initWithData:folder2]; // load data from folder2
Dies funktioniert ohne Lecks in Ordnung, und ich bin mit dem ARC Erraten fügt eine [object Release] vor der neuen Aufgabe. Mein Problem ist die Daten innerhalb 'Objekt' freigegeben nach der neue Satz ist zugeordnet, und ich habe nicht genug Speicher. Was ich wirklich möchte, ist:
object = nil;
<function to pop the pool, wait till everything is deallocated>
object = [MyObject alloc] initWithData:folder2]; // load data from folder2
aber ich bin mir nicht sicher, wie das geht. Ich könnte die neue Zuweisung nach einer Verzögerung auf einem Performselektor durchführen, aber es fühlt sich an, als würde ich im Dunkeln drehen und ein bisschen hacken. Es gibt wahrscheinlich einen richtigen Weg, dies zu tun?
PS Ich habe versucht, nach einer Antwort zu suchen, aber alle Ergebnisse beziehen sich auf Speicherlecks und wie man sicherstellt, dass Variablen den Gültigkeitsbereich verlassen und Variablen auf Null setzen. Mein Problem ist nicht das, es ist mehr von a Timing Sache.
UPDATE
Danke für die Antworten, würde ich schon versucht
object = nil;
object = [MyObject alloc] initWithData:folder2];
und es nicht funktioniert hat. Ich war mir nicht sicher, ob es sein sollte oder nicht. Jetzt verstehe ich, dass es ist soll funktionieren, aber ich muss etwas anderes halten für den Bruchteil einer Sekunde halten. Ich habe NSLogs in allen meinen init/dealloc-Methoden, und ich kann zuerst alle Inits der neuen Klasseninstanzen (von MyObjects-Ivars) aufrufen und dann fast unmittelbar nach (innerhalb von ein paar Millisekunden) die Dealloc von MyObject gefolgt von den Deallocs seiner Ivars. Ich habe auch die @autorelease ausprobiert, aber das Gleiche passiert.
Ich habe während des Projekts gesucht und den ganzen Code eingefügt, der für mich relevant sein könnte.
@interface AppDelegate : UIResponder <UIApplicationDelegate>;
@property PBSoundSession *soundSession;
@end
//--------------------------------------------------------------
@implementation AppDelegate
// onTimer fired at 60Hz
-(void)onTimer:(NSTimer *) theTimer {
[oscReceiver readIncoming]; // check incoming OSC messages
// then do a bunch of stuff with _soundSession;
}
@end
//--------------------------------------------------------------
@implementation OscReceiver
-(void)readIncoming {
AppDelegate *appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
// parse all incoming messages
if(bLoadNewSoundBank) {
NSString *newFolder = parseNewFolder();
appDelegate.soundSession = nil;
appDelegate.soundSession = [MyObject alloc] initWithData:newFolder];
}
}
@end
//--------------------------------------------------------------
@implementation GuiController
// onTimer fired at 10Hz
-(void)onTimer:(NSTimer *) theTimer {
PBSoundSession *soundSession = appDelegate.soundSession;
// update gui with received values
}
@end
Ich dachte, es könnte die ‚soundSession‘ lokaler Variable in dem GuiController sein :: OnTimer für die Dauer dieses Verfahrens auf die alte appDelegate.soundSession halten, aber zu meiner Überraschung all GUI-Code zu kommentieren out (den Timer zu deaktivieren, machte keinen Unterschied.
Gibt es eine Möglichkeit herauszufinden, wer noch an meiner appDelegate.soundSession festhält? Ich habe einen Haltepunkt platziert, wo ich ihn auf Null gesetzt habe, konnte aber keine nützlichen Informationen finden. Ich habe das Instrument in Allocation-Template ausprobiert, konnte dort aber auch nichts Nützliches finden (wahrscheinlich weil ich nicht weiß, wo ich hinschauen soll).
So sieht mein Zuordnungs-Track aus, Sie können sehen, dass der Speicher alle ein bisschen zu spät freigegeben wird! .
Nun, Sie würden viel von dem bekommen, was Sie wollen, indem Sie einfach "object = nil;" ausführen, bevor Sie das neue Objekt zuweisen/initialisieren. –