Recentemente mi sono imbattuto in questo problema con alcune viste che sto valutando per i calcoli delle dimensioni sul thread in background. Sbalzando setAnimationsEnabled:
, ho trovato che il tempo solo in cui stavo disattivando le animazioni dal thread in background era -[UIImageView setImage:]
.
Perché questo punto di vista non è mai stato reso e immagine cambia non sono stati richiesti per il mio calcolo, sono stato in grado di racchiudere questa prova in una chiamata thread principale:
if ([NSThread isMainThread]) {
self.answerImageView.image = [UIImage imageNamed:imgName];
}
Vale la pena notare non mi ha colpito questo problema nella visualizzazione di un'istanza iniziale, perché ho già caricare le mie opinioni template nel thread principale per evitare un problema di carico XI ter.
Altri problemi possono essere più complessi, ma si dovrebbe essere in grado di trovare soluzioni alternative simili. Ecco la categoria che uso per rilevare la disabilitazione di sfondo delle animazioni.
#import <UIKit/UIKit.h>
#import <JRSwizzle/JRSwizzle.h>
#ifdef DEBUG
@implementation UIView (BadBackgroundBehavior)
+ (void)load
{
NSError *error = nil;
if (![self jr_swizzleClassMethod:@selector(setAnimationsEnabled:) withClassMethod:@selector(SE_setAnimationsEnabled:) error:&error]) {
NSLog(@"Error! %@", error);
}
}
+ (void)SE_setAnimationsEnabled:(BOOL)enabled
{
NSAssert([NSThread isMainThread], @"This method is not thread safe. Look at the backtrace and decide if you really need to be doing this here.");
[self SE_setAnimationsEnabled:enabled];
}
@end
#endif
Aggiornamento
Si scopre che in realtà UIWebView
rende le chiamate non sicuri per l'setAnimationsEnabled:
durante la visualizzazione di un elemento di supporto (rdar: // 20.314.684). Ciò rende il metodo di cui sopra molto doloroso per avere attiva tutto il tempo se la vostra applicazione permette di contenuti Web arbitrario. Invece ho iniziato ad usare il metodo seguito in quanto mi permette di girare il punto di interruzione e si spegne e continuare dopo il fallimento:
#import <UIKit/UIKit.h>
#import <objc/runtime.h>
#ifdef DEBUG
void SEViewAlertForUnsafeBackgroundCalls() {
NSLog(@"----------------------------------------------------------------------------------");
NSLog(@"Background call to setAnimationsEnabled: detected. This method is not thread safe.");
NSLog(@"Set a breakpoint at SEUIViewDidSetAnimationsOffMainThread to inspect this call.");
NSLog(@"----------------------------------------------------------------------------------");
}
@implementation UIView (BadBackgroundBehavior)
+ (void)load
{
method_exchangeImplementations(class_getInstanceMethod(object_getClass(self), @selector(setAnimationsEnabled:)),
class_getInstanceMethod(object_getClass(self), @selector(SE_setAnimationsEnabled:)));
}
+ (void)SE_setAnimationsEnabled:(BOOL)enabled
{
if (![NSThread isMainThread]) {
SEViewAlertForUnsafeBackgroundCalls();
}
[self SE_setAnimationsEnabled:enabled];
}
@end
#endif
Con questo codice, è possibile interrompere la vostra applicazione con l'aggiunta di un punto di interruzione simbolica sulla SEViewAlertForUnsafeBackgroundCalls
o semplicemente attaccare un punto di interruzione nel corpo della funzione.
Gist
fonte
2014-10-02 20:18:20
non so il motivo dietro di esso, ma ho avuto esattamente lo stesso problema ed è stato risolto quando ho rimosso un tableView: willDisplayCell: forRowAtIndexPath: il metodo che ha usato per chiamare un sacco di performSelectorInBackground per visualizzare le immagini. Questo può aiutare o dare qualche suggerimento per risolvere il problema. – Mohammad
in realtà ho trovato out.It succede quando si fa roba UIKit in background thread.Here è il link che spiega tutto. http://stackoverflow.com/questions/18281097/uiviewcontroller-animations-stop-working – user1010819