programación - iOS 7-Diferencia entre viewDidLoad y viewDidAppear
swift lenguaje de programacion caracteristicas (6)
Lo siento, pero esta puede no ser una pregunta de programación per se, sino más una consulta sobre la naturaleza de las funciones del ciclo de vida de iOS.
Tengo una aplicación en la que tengo una función que crea cuatro matrices y las rellena mediante consultas a la base de datos. Al principio, llamé a la función desde la función viewDidLoad
, sin embargo, cada vez que se carga la vista, toma tiempo (alrededor de 3-4 segundos) antes de que realmente aparezca la vista. Entonces, lo que hice fue crear un activityViewIndicator
y mi función viewDidLoad
parece a algo así:
- (void)viewDidLoad:(BOOL)animated{
[super viewDidLoad];
NSLog(@"viewDidLoad Entered");
[self.activityIndicatorView startAnimating];
partInput.delegate = self;
brandInput.delegate = self;
barcodeInput.delegate = self;
itemNameInput.delegate = self;
//initializeArrays is the function that initializes the arrays
[self initializeArrays];
[self.activityIndicatorView stopAnimating];
}
Sin embargo, esto no funciona, ya que la función viewDidLoad
se activa cuando la aplicación aún se encuentra en la Vista anterior. La vista solo se muestra después de que viewDidLoad
ya está hecho. Entonces, lo que hice fue mover la inicialización de la matriz a mi función viewDidAppear
que se ve así:
- (void)viewDidAppear:(BOOL)animated{
NSLog(@"viewDidAppear loaded successfully");
[self.activityIndicatorView startAnimating];
partInput.delegate = self;
brandInput.delegate = self;
barcodeInput.delegate = self;
itemNameInput.delegate = self;
[self initializeArrays];
[self.activityIndicatorView stopAnimating];
}
Sin embargo, cuando implementé esto, no hubo demora alguna, lo que hizo que activityIndicatorView fuera inútil.
Mi pregunta es, ¿por qué me parece que hay una "diferencia de rendimiento" entre viewDidLoad
y viewDidAppear
?
El activityIndicatorViews
solo se animará si el hilo principal (el hilo de UI) no está ocupado. viewDidLoad:
y viewDidAppear:
ambos se ejecutan en el hilo principal. Si, como mencionas, el método initializeArrays
no se ejecuta en un hilo separado, entonces activityIndicatorViews
nunca tendrá tiempo para animar.
No hay absolutamente ninguna diferencia de rendimiento entre viewDidLoad: y viewDidAppear :. Ambas son funciones normales que se ejecutan en el hilo principal. Si su método initializeArrays tarda 3 segundos en cargarse, tardará 3 segundos en el método que usted elija. Como no está cambiando explícitamente los hilos, cualquier función a la que llame initializeArrays no se cerrará hasta que haya finalizado.
La llamada a [self.activityIndicatorView startAnimating] básicamente "marcará" activityIndicatorView para que otra función de IU en el hilo principal la comience a animar. (Esta es la razón por la cual el hilo principal o ''UI'' es importante, porque todas las animaciones y actualizaciones visuales de la pantalla están coordinadas en él). Por lo tanto, la función que realmente activará el indicador activityIndicator no se ejecutará hasta que finalice InitializeArrays y ya haya llamado a "stopAnimating".
Prueba esto:
- (void)viewDidLoad:(BOOL)animated{
[super viewDidLoad];
NSLog(@"viewDidLoad Entered");
[self.activityIndicatorView startAnimating];
partInput.delegate = self;
brandInput.delegate = self;
barcodeInput.delegate = self;
itemNameInput.delegate = self;
}
- (void)viewDidAppear:(BOOL)animated{
//initializeArrays is the function that initializes the arrays
[self initializeArrays];
[self.activityIndicatorView stopAnimating];
}
Siga el siguiente Ciclo de vida del controlador de View Every Time. Se sorprenderá con la codificación y el rendimiento de su aplicación de esta manera.
Sin embargo, cuando carga cosas desde un servidor (o procesamiento de datos pesados), también debe pensar en la latencia. Si empaqueta todas sus comunicaciones de red en viewDidLoad o viewWillAppear , se ejecutarán antes de que el usuario vea la vista, lo que podría resultar en una congelación corta de su aplicación. Puede ser una buena idea mostrar primero al usuario una vista despoblada con un indicador de actividad de algún tipo. Cuando haya terminado con su red, que puede tomar uno o dos segundos (o incluso puede fallar, ¿quién sabe?), Puede completar la vista con sus datos. Buenos ejemplos de cómo se puede hacer esto se pueden ver en varios clientes de Twitter. Por ejemplo, cuando ve la página de detalles del autor en Twitterrific, la vista solo dice "Cargando ..." hasta que las consultas de la red se hayan completado.
ViewDidLoad llama solo una vez cuando inicializó su ViewController pero Viewdidapper llama cada vez.
Voy a señalarte los documentos de Apple porque creo que hay una necesidad de más explicaciones sobre el ciclo de vida del Controlador de visualización que solo responder a tu pregunta como está redactado.
En última instancia, su controlador de vista tiene un ciclo de vida:
init: sin embargo, usted inicializa su controlador de vista
viewWillLoad / viewDidLoad: se llama cuando se construye la vista (a través de la primera llamada para recuperar la UIView del controlador de vista a través de su propiedad de vista, también conocida como carga diferida)
viewWillAppear: cuando la vista se está preparando para aparecer de forma inmediata (animada == NO) o ver una transición (animada == SÍ)
viewDidAppear: - si la apariencia de la vista no se canceló y la vista del controlador de la vista aparece por completo
viewWillDisappear: complementa viewWillAppear:
viewDidDisappear: complementa viewDidAppear:
viewWillUnload / viewDidUnload: API en desuso cuando la vista se descarga debido a restricciones de memoria (no se preocupe más por esto)
dealloc: el controlador de vista se está desasignando
Sin embargo, al final, creo que su problema puede ser que está bloqueando el hilo principal con la inicialización de su matriz. Deberías leer sobre la programación asíncrona, pero mientras tanto podrías hacer algo como esto:
- (void)viewDidLoad
{
[super viewDidLoad];
// other stuff
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
typeof(weakSelf) strongSelf = weakSelf;
if (strongSelf) {
[strongSelf initializeArraysSynchronously];
dispatch_async(dispatch_get_main_queue(), ^{
strongSelf.doneIntializingArrays = YES;
[strongSelf.activityIndicatorView stopAnimating];
});
}
});
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
if (!self.doneInitializingArrays) {
[self.activityIndicatorView startAnimating];
}
}
Ver carga : primer método, que se llama cuando la vista se carga por primera vez pero no aparece en la pantalla / ventana, solo se carga.
solo se llama una vez cuando la vista se carga por primera vez.
La vista apareció : una vez que se llame aWallAppear, se invocará viewDidAppear. Significa que la vista aparece en la pantalla ahora.
Llamado número de veces a medida que el usuario se mueve de ese controlador de vista a otro controlador de vista y regresa.
**
- Ver ciclo de vida
**
1) ViewDidLoad (llamado solo cuando la vista se carga por primera vez), luego 2) ViewWillAppear (se llamará número de veces), luego 3) ViewDidAppear (se llamará número de veces), luego 4) ViewWillDisAppear (se llamará número de veces) veces), luego 5) ViewDidDisAppear (se llamará número de veces)