2015-12-29 22 views
5

Domanda semplice.Generatori PHP - Garbage Collection

Quando o come, da PHP o da te stesso i generatori distruggono i loro stack?

Prendiamo il seguente esempio:

function doWork(): Generator 
{ 
    // create some objects. 
    $o1 = new stdClass(); 
    $o2 = new stdClass(); 

    // pause here and wait for data. 
    $value = yield 1; 

    // By referencing the above objects, they shouldn't destruct. 
    $o1->property = $value; 
    $o2->property = $value; 

    yield $o1; 
    yield $o2; 

    // End of stack. 
} 

// Create the generator. 
$generator = doWork(); 

$value = $generator->current(); // $value will equal 1. 

if ($x) { 
    $generator->send('Hello, World!'); // Continue execution of the generator. 
    $o1 = $generator->current(); 
    $generator->next(); 
    $o2 = $generator->current(); 
    $generator->next(); // Complete the generator 

    var_dump($o1); 
    var_dump($o2); 
} else { 
    // Do nothing with the generator. 
} 

// Carry on with script ... 

In questo esempio un generatore viene avviato e vengono creati due oggetti. A questo punto viene restituito e vengono richiesti ulteriori dati.

È stata raggiunta un'istruzione IF.

Caso 1

Se $x è vero, il valore "Hello, World!" verrà inviato al generatore e gli oggetti sarà popolata con le loro nuove proprietà.

Alla successiva lettura dei dati restituiti, gli oggetti verranno restituiti.

Caso 2

Se $x è falso, non sarà più utilizzato il generatore.

Domanda

Nel caso 1, mi sarei aspettato la pila di chiudere come qualsiasi altra funzione, ma ciò che accade al generatore in caso 2? Questo e tutti i restanti riferimenti agli oggetti rimangono in memoria fino al termine dello script?

Oppure provoca la perdita di riferimento a $generator e tutti i riferimenti interni vengono cancellati?

risposta

2

Ci sono due condizioni in cui un generatore distrugge suo contesto di esecuzione (che comprende anche la tabella delle variabili):

  1. Se il generatore termine dell'esecuzione. Ciò può accadere eseguendo uno return (incluso il ritorno implicito alla fine della funzione) o attraverso un'eccezione non rilevata durante l'esecuzione del generatore.
  2. Se tutti i riferimenti all'oggetto generatore vengono abbandonati.

Quindi, no, il generatore non vivrà fino alla fine della sceneggiatura. Sarà distrutto una volta che la variabile $generator non rientra nello scope, a quel punto il generatore rinuncerà ai suoi riferimenti ai valori delle variabili e ad altri stati di esecuzione.

È possibile osservare facilmente l'ordine di distruzione creando una classe che è echo s nel distruttore e quindi creando un'istanza di questa classe in una variabile locale.

+0

Nessun problema quindi, acclamazione compagno – Flosculus