2009-07-23 12 views

Antwort

8

Die beiden Methoden machen verschiedene Dinge. Wenn Sie einen Timer besitzen (Sie haben ihn behalten oder ihm zugeteilt oder ihn kopiert), sollten Sie ihn freigeben. Wenn Sie es in einer Ausführungsschleife eingeplant haben, müssen Sie es ungültig machen, damit die Ausführungsschleife es freigibt. Wenn Sie beide Dinge getan haben, müssen Sie den Timer freigeben und ungültig machen (allerdings ist es normalerweise ausreichend, wenn die Laufschleife, die den Timer besitzt, ausreicht).

+0

erste Freigabe und dann ungültig in Freigabe? kann ich ein Argument mit zwei Argumenten im Selektor senden? –

+0

Zuerst ungültig machen, dann loslassen (wenn Sie es besitzen). Bitte klären Sie Ihre letzte Frage. Wenn Sie fragen, ob Sie den Timer mit nur einem Aufruf ungültig machen und freigeben können, ist die Antwort nein, es sei denn, Sie erstellen Ihre eigene Komfortmethode, die diese beiden Dinge erledigt, und rufen diese Methode auf. – Felixyz

+0

kann ich zusätzliches Argument mit @selector in NSTIMER senden? –

0

Das ist die richtige Weise, um einen Zeitgeber freizugeben, der möglicherweise noch ausgeführt wird (und Sie beenden möchten).

+1

unter der Annahme, dass Sie den Timer an erster Stelle besitzen ... wenn Sie nicht tun, dann wird der '-Release'-Aufruf abstürzen. Oder sollte. –

1

Immer, Release ist das letzte, was Sie tun. Sobald Sie etwas freigegeben haben, gibt es keine Garantie dafür, dass es sicher ist, das Objekt zu dereferenzieren, was bedeutet, dass es nicht mehr sicher ist, eine Nachricht zu senden.

15

[timer release] muss nur aufgerufen werden, wenn Sie den Timer "besitzen". Von Apple's documentation:

Da hält die Laufschleife die Timer, aus der Perspektive der Speicherverwaltung gibt es normalerweise keine Notwendigkeit, einen Verweis auf einen Timer zu halten, sobald Sie es geplant haben. Da der Zeitgeber als Argument übergeben wird, wenn Sie seine Methode als Selektor angeben, können Sie einen Wiederholungstimer bei Bedarf innerhalb dieser Methode ungültig machen. In vielen Situationen möchten Sie jedoch auch die Möglichkeit, den Timer zu deaktivieren - vielleicht sogar bevor er gestartet wird. In diesem Fall müssen Sie einen Verweis auf den Zeitgeber beibehalten, damit Sie ihm bei Bedarf eine ungültige Nachricht senden können. Wenn Sie einen nicht geplanten Zeitgeber erstellen (siehe “Unscheduled Timers”), müssen Sie einen starken Verweis auf den Zeitgeber beibehalten (in einer Umgebung mit Referenzzählung, die Sie beibehalten), damit er nicht freigegeben wird, bevor Sie ihn verwenden.

Was bedeutet das?

Wenn Sie alloc und init ein Timer, müssen Sie auch release es, etwa so:

NSTimer * timer = [[NSTimer alloc] initWith...]; 

NSRunLoop * runLoop = [NSRunLoop currentRunLoop]; 
[runLoop addTimer:timer forMode:NSDefaultRunLoopMode]; 
[timer release]; 

... 
... 

[timer invalidate]; 
timer = nil; 

Sobald der Timer auf die Laufschleife hinzugefügt wurde, gibt es keinen Grund, einen Verweis auf sie zu halten mehr , da die Laufschleifen es besitzen. In diesem Fall, wie gezeigt, würden Sie release den Timer, sobald Sie es in die Laufschleife hinzufügen, und dann einfach invalidate es, wenn Sie fertig sind. Die letzte Zeile (Timer auf nil einstellen) dient der Sicherheit. Der Aufruf von invalidate führt dazu, dass der Timer freigegeben wird (durch die Laufschleife), so dass es unsicher ist, eine Referenz zu behalten, die darauf zeigt. Wenn Sie den lokalen Verweis auf nil festlegen, bleiben die Daten koscher.

Wenn jedoch erstellen Sie einen Timer eine der Bequemlichkeit Methoden wie folgt:

NSTimer * timer = [NSTimer scheduledTimerWithTimeInterval ...]; 

Sie tun nicht brauchen [timer release] überhaupt zu nennen! Die Komfortmethode fügt den Zeitgeber der Laufschleife hinzu, der sie dann gehört, so dass Sie keine Speicherverwaltung für das zurückgegebene Zeitgeberobjekt durchführen müssen.Sie würden einfach invalidate der Timer, wenn Sie ihn nicht mehr verwenden möchten:

[timer invalidate]; 
timer = nil; 

Oder, wenn der Timer nicht wiederholen gesetzt wurde, würden Sie absolut gar nichts, da es nach dem ersten Aufruf freigegeben würde .

+2

Sobald Sie [timer release] aufrufen, ist es nicht gut anzunehmen, dass der Timer noch gültig ist. Im Falle einer einzigen Methode ist dies fast immer sicher, aber der Code wäre besser, wenn die [Timer-Freigabe] nach dem [Timer ungültig] gesetzt würde. –

+0

Eine großartige praktische Antwort. – Ross

Verwandte Themen