Un certo numero di classi Cocoa Touch sfruttano un modello di progettazione di eventi coalescenti. UIViews
, ad esempio, ha un metodo setNeedsLayout
che provoca la chiamata di layoutSubviews
nel prossimo futuro. Ciò è particolarmente utile in situazioni in cui un numero di proprietà influenza il layout. Nel setter di ciascuna proprietà è possibile chiamare [self setNeedsLayout]
che garantirà il layout verrà aggiornato, ma impedirà molti aggiornamenti (potenzialmente costosi) al layout se più proprietà vengono modificate contemporaneamente o anche se una singola proprietà è stata modificata più volte all'interno di una iterazione del ciclo di esecuzione. Altre costose operazioni come la coppia di metodi setNeedsDisplay
e drawRect:
seguono lo stesso schema.Implementare un pattern Debounced/Coalesced in Cocoa Touch come `layoutSubviews`
Qual è il modo migliore per implementare pattern come questo? In particolare vorrei collegare un numero di proprietà dipendenti a un metodo costoso che deve essere chiamato una volta per iterazione del ciclo di esecuzione se una proprietà è cambiata.
Possibili soluzioni:
Utilizzando un CADisplayLink
o NSTimer
si potrebbe ottenere qualcosa di lavoro come questo, ma entrambi sembrano più coinvolti di quanto necessario e non sono sicuro che cosa le implicazioni sulle prestazioni di aggiungere questo alla molti oggetti (specialmente i timer) sarebbero. Dopotutto, le prestazioni sono l'unica ragione per fare qualcosa del genere.
ho usato qualcosa di simile, in alcuni casi:
- (void)debounceSelector:(SEL)sel withDelay:(CGFloat)delay {
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:sel object:nil];
[self performSelector:sel withObject:nil afterDelay:delay];
}
Questa grande opera in situazioni in cui un ingresso utente deve attivare solo alcuni eventi quando un'azione continua, o cose del genere. Sembra goffo quando vogliamo garantire che non vi sia alcun ritardo nell'innescare l'evento, ma vogliamo semplicemente effettuare chiamate in coalesce all'interno dello stesso ciclo di esecuzione.
Se sei interessato ad agire in modo preciso per ciclo di esecuzione, penserei che tu voglia un [osservatore del ciclo di esecuzione] (https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ multithreading/RunLoopManagement/RunLoopManagement.html # // apple_ref/doc/uid/10000057i-CH16-SW22). Per un breve esempio, vedere [Esecuzione selettore all'inizio/fine del ciclo di esecuzione] (http://stackoverflow.com/q/16789342). –