Ho incontrato questo problema un paio di volte e voglio conoscere l'approccio corretto da prendere.Impedire ad ARC di rilasciare qualcosa che non è attualmente in uso ma lo sarà presto?
Per un esempio, diciamo che sto scrivendo un'app per iPhone e desidero una classe di visualizzazione di avviso personalizzata che utilizza blocchi.
Così ho scrivere la classe, poi in seguito nel mio codice vado:
MyAlertView *alert = [MyAlertView alertWithBlahBlahBlah...];
[alert addButton:@"button" withBlock:^{ ... }];
[alert show];
Da qualche parte nella classe di visualizzazione avviso, abbiamo
- (void)addButton:(NSString *)button withBlock:(void (^))block {
[_blocks setObject:[block copy] forKey:button];
}
- (void)show {
... drawing stuff ...
UIButton *button = ...
[button addTarget:self selector:@selector(buttonPressed:) ...];
...
}
- (void)buttonPressed:(id)sender {
((void (^)())[_blocks objectForKey:[sender title]])();
}
Quindi, la vista avviso ora si presenta va bene. Il problema è che, se tocco un pulsante, tenta di inviare il selettore buttonPressed:
all'oggetto MyAlertView
visualizzato. Il dispositivo MyAlertView
è stato tuttavia rimosso dal superview in questo momento. ARC decide che poiché la vista di avviso non è più di proprietà di nessuno, dovrebbe essere deallocata, non sapendo che un pulsante ha bisogno di segnalarlo in futuro. Ciò provoca un arresto anomalo quando si tocca il pulsante.
Qual è il modo corretto per mantenere la vista di avviso in memoria? Potrei rendere l'oggetto MyAlertView
una proprietà della classe che lo sta usando, ma questo è un po 'sciocco (cosa succede se voglio mostrare due avvisi contemporaneamente?).
Perché è stato rimosso dalla sua superview se è ancora sullo schermo? –
Se non si ha un riferimento ad esso da qualche parte, allora non si sarebbe in grado di deallocarlo quando si vuole "ad un certo punto nel futuro", quindi è necessario mantenere ** qualche ** tipo di riferimento a esso. Questo potrebbe essere in una proprietà, come suggerisci tu, o forse una serie di oggetti "memorizzati nella cache" di cui sarai in grado di disporre quando la tua classe viene deallocata. – lnafziger
@JoshCaswell Questo è principalmente un esempio forzato. Stavo facendo qualcosa di simile anche se l'azione sarebbe avvenuta dopo che la vista fosse stata rimossa dallo schermo. –