5

Ho sentito che dovrei sempre usare weakSelf in blocchi per evitare i cicli di conservazione, ma per quanto riguarda i blocchi di spedizione? In questo caso, il mio metodo gestisce una risposta di errore dal mio server nel codice seguente:Devo utilizzare "weakSelf" In un blocco di spedizione?

//handling server errors (particularly "Token Refresh Failed" ones) 
-(void)handleServerErrorResponse:(NSString *)error { 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     UIAlertController *alertController = [DialogHelper getAlertForSimpleAuthError:error]; 
     if ([error isEqualToString:@"Your login session has expired"]) { 
      [alertController addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) 
      { 
       [MyModelDataCenter emptyDataCenter]; 
       [MyAPIInterface sharedInstance].authToken = nil; 
       NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; 
       [defaults removeObjectForKey:@"authToken"]; 
       [defaults removeObjectForKey:@"defaultUserObjectDictionary"]; 
       [defaults synchronize]; 
       [AuthenticationHelper sharedInstance].loggedInUser = nil; 
       [self.navigationController popToRootViewControllerAnimated:YES]; 
      }]]; 
     } 
     else { 
      [alertController addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:nil]]; 
     } 
     [self presentViewController:alertController animated:YES completion:nil]; 
    }); 
} 

Dovrei usare weakSelf in questo blocco lo stesso che lo faccio in altri blocchi?

risposta

8

È necessario utilizzare la "danza" debole-forte per evitare un ciclo di mantenimento solo quando c'è un ciclo di mantenimento persistente. Perché ciò accada, due condizioni devono essere soddisfatte:

  • il blocco è di proprietà di un oggetto a cui fa riferimento all'interno del blocco
  • il proprietario non rilascia il blocco prima di un proprio deallocazione

Se una di queste cose non è vera, non esiste un ciclo di conservazione permanente e nessun problema.

In questo caso, è vero. In generale, Blocchi messi nelle code di spedizione non saranno soggetti a cicli di conservazione, a meno che non si mantenga il blocco in un ivar da riutilizzare.

+0

Puoi dare un esempio di quando conserverebbe? – sbarow

+1

Ecco un esempio, anche se con pochi passaggi intermedi: http://stackoverflow.com/q/11822476/603977 –

+0

Grazie per averlo spiegato così bene! E grazie per l'esempio! :) – Rafi

5

Anche io sono d'accordo con Josh e hanno concordato fin dall'inizio, che non v'è alcun motivo per weakifying self, se è non è necessario (il blocco non è in possesso da un oggetto di riferimento), in passato la maggior parte indebolito self come predefinito. (Credo che i cambiamenti di maggioranza.)

Tuttavia, non ci può essere un motivo per weakify self ancora non c'è conservano ciclo:

Immagine che si dispone di un oggetto istanza che viene riempito da un blocco di lunga durata . È possibile che l'oggetto istanza possa morire mentre il blocco è in esecuzione, i. e. perché l'utente l'ha cancellato. In tal caso, il blocco riempirebbe un oggetto istanza che non ha più utilità e che è stato rimosso dal modello, ma ancora vivo, perché il blocco lo trattiene. Indebolendolo liberarlo e impostare il catturato self a nil, ciò che è facile da controllare e di solito non fa semplicemente nulla.

Ma io davvero non penso e non ho mai pensato che questo scenario giustifica una regola empirica "Weakify di default".

+0

Stai dicendo che se la mia chiamata API richiede molto tempo a causa di una connessione Internet lenta per ottenere una risposta dal server, e se apro il 'UIViewController' che ha questo metodo di gestione degli errori, la mia app andrà in crash? – Rafi

+1

No, non l'ho detto. Quello che succede dipende dal tuo codice concreto. Quello che dico è: se hai un forte riferimento all'oggetto, non sarà deallocato, anche nessun altro lo sta riferendo. Che cosa fa con la tua app? Non posso saperlo. –

+0

Ok, grazie per le informazioni. Mi prenderò cura di queste cose :) – Rafi