2012-05-24 14 views
26

He oído que la instanciación lenta de objetos en iOS es bastante común, sin embargo, no estoy exactamente seguro de cuándo debo usarla. ¿Podría alguien dar una breve explicación de cuándo debería usar instanciación lenta y cuándo debería inicializar mis propiedades en el método init?Cuándo usar instancias perezosas en iOS?

Mi preocupación con respecto a la instanciación lenta es que requiere una gran cantidad de código (en comparación con simplemente escribirlo todo en el método init), especialmente si tiene varias propiedades para inicializar.

+0

¿Cómo se requiere una gran cantidad de código en comparación con hacerlo en init? Generalmente no agrega mucho más que jus haciendo cosas en init –

+0

No tiene sentido en pequeños proyectos y con nuevos dispositivos. Si le preocupa la memoria, debe usar instanciación lenta. – ymutlu

+0

@ymutlu ¿Puedes explicar por qué no tiene sentido en pequeños proyectos y con nuevos dispositivos? –

Respuesta

18

Para ampliar mi comentario. A veces, esta técnica es buena si tienes un objeto que solo necesita configurarse una vez y tiene alguna configuración involucrada que no quieras saturar tu método init.

- (UIView *)myRoundedView; 
{ 
    if (!_myRoundedView) { 
     _myRoundedView = [[UIView alloc] initWithFrame:<#some frame#>]; 
     _myRoundedView.layer.cornerRadius = 10.f; 
     _myRoundedView.backgroundColor = [UIColor colorWithWhite:0.f alpha:0.6f]; 
     _myRoundedView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 
    } 
    return _myRoundedView; 
} 

Es un ejemplo bastante artificial pero puede comenzar a ver el mérito. Los métodos deberían ser como las clases y hacer una cosa bien. Este método devuelve la vista redondeada que quiero. Si insertara este código en el método init, entonces el método init ahora tendría que conocer los detalles esenciales de cómo crear una instancia y configurar esta vista y cualquier otro objeto que abofetee allí.

11

Como con cualquier técnica, no hay una sola regla única que le diga cuándo crear una instancia perezosa de algo. Creo que un buen consejo es usar instancias perezosas para cosas que son caras de crear instancias. Si algo necesita hacer una gran cantidad de acceso a disco o red, o toma mucho tiempo de CPU para configurarlo, es mejor posponer ese trabajo hasta que sea realmente necesario (o hacerlo en segundo plano). Particularmente para las características que un usuario puede o no usar, no tiene sentido perder mucho tiempo en -init (o similar) configurando cosas, y al hacerlo puede contribuir a hacer que su aplicación se sienta lenta para el usuario.

Dicho esto, debe evitar la optimización prematura. No dedique mucho tiempo a escribir código complicado para ayudar con el rendimiento hasta que haya hecho las cosas de la manera más obvia, haya encontrado un problema de rendimiento y haya perfilado su código para comprender completamente el problema. Después de que hayas hecho eso, puedes comenzar a hacer cambios para mejorar las cosas.

13

Es bueno en situaciones donde tiene objetos que pueden tener una gran huella de memoria, por lo que puede evitar inicializar todos estos objetos costosos en el momento de la inicialización de la clase de contenedor. La inicialización diferida puede conservar el consumo de memoria en varias situaciones ...

Sin embargo, está claro que si todos los objetos necesitan una inicialización después o inmediatamente después de la inicialización del objeto contenedor, la inicialización lenta no tiene sentido y un constructor estándar la inicialización debe ser utilizada.

La inicialización diferida se debe utilizar en caso de que haya objetos opcionales dentro de una clase que nunca se podrían inicializar durante todo el flujo de trabajo de la clase.

3

No sólo por la memoria y el rendimiento, mira esto, he aquí otro ejemplo:

- (NSArray *)validElements{ 
    if (!_validElements) { 
     _validElements = [[NSArray alloc] initWithObjects: 
          @"mystuff",@"generaldescription",@"title",@"autor", 
          @"version",@"date",@"context",@"operatingsystem",@"kindofdevice", 
          @"deviceversion",@"rule",@"daytime",@"time",@"location",@"deviceheading", 
          @"region",@"language",nil]; 
    } 
    return _validElements; 
} 

Puede utilizar instanciación perezosa para hacer un init personalizado o configuración especial y sí también esto beneficia a la memoria y el rendimiento.

Cuestiones relacionadas