Per anni ho seguito un grande schema chiamato Target-Action che si presenta così:Il modello di progettazione Target-Action è diventato una cattiva pratica sotto ARC?
Un oggetto chiama un selettore specificato su un oggetto di destinazione specificato quando arriva il momento della chiamata. Questo è molto utile in molti casi diversi in cui è necessario un semplice callback a un metodo arbitrario.
Ecco un esempio:
- (void)itemLoaded {
[specifiedReceiver performSelector:specifiedSelector];
}
Sotto ARC ora scopre che facendo qualcosa di simile ad un tratto è diventata pericolosa.
Xcode lancia un avvertimento che va in questo modo:
performSelector può causare una perdita perché il suo selettore è sconosciuta
Naturalmente il selettore è sconosciuto poiché, come parte del progetto di destinazione-Azione pattern puoi specificare il selettore che desideri per ottenere una chiamata quando succede qualcosa di interessante.
Ciò che mi infastidisce di più di questo avviso è che dice che può esserci una potenziale perdita di memoria. Dal mio punto di vista, ARC non modifica le regole di gestione della memoria, ma invece automatizza semplicemente l'inserimento di messaggi di conservazione/rilascio/autorelease nelle posizioni corrette.
Un'altra cosa da notare qui: -performSelector: ha un valore di ritorno id
. ARC analizza le firme dei metodi per capire attraverso l'applicazione delle convenzioni di denominazione se il metodo restituisce un oggetto conteggio di ritenzione +1 o meno. In questo caso ARC non sa se il selettore è un factory -newFooBar
o semplicemente chiama un metodo worker unsuspicious (che è quasi sempre il caso di Target-Action comunque). In realtà, ARC avrebbe dovuto riconoscere che non mi aspetto un valore di ritorno, e quindi dimenticare qualsiasi potenziale valore di ritorno conteggiato di +1. Guardandolo da quel punto di vista posso vedere da dove proviene ARC, ma ancora c'è troppa incertezza su ciò che questo significa in pratica.
Ciò significa ora sotto ARC qualcosa può andare storto che non accadrà mai senza ARC? Non vedo come questo potrebbe produrre una perdita di memoria. Qualcuno può fornire esempi di situazioni in cui ciò è pericoloso da fare e in quale caso viene creata esattamente una perdita?
ho davvero Googled l'inferno fuori di internet, ma non ha trovato alcun sito che spiega il motivo per cui .
Hai completamente ragione. Ma nel mio caso ignoro completamente il valore di ritorno, che in una conseguenza logica significa che non ci può essere un problema in questa posizione. Ho persino provato a lanciare a vuoto, a ponte, __unsafe_unretained, ecc. - l'unico modo per sbarazzartene è spostarsi sui blocchi (che provoca una pletora di altri problemi) o disabilitare l'avviso nelle impostazioni delle fasi di costruzione. –
Vedere la mia modifica per disattivare l'avviso solo per un bit di codice. – mattjgalloway
Due cervelli, lo stesso pensiero. Grande! :-) (digitato la mia risposta allo stesso tempo. contiene ulteriori informazioni sulla disabilitazione dell'avviso) –