2012-03-05 40 views
21

Tengo un código que me gustaría ejecutar solo una vez en mi MainViewController. Debería ejecutarse cada vez que el usuario inicie la aplicación, pero solo después de que se haya cargado MainViewController.Haciendo que algunos códigos solo se ejecuten una vez

No quiero ejecutarlo en -(void)applicationDidFinishLaunching:(UIApplication *)application.

Ésta es la idea que tenía:

MainViewController.h

@interface IpadMainViewController : UIViewController <UISplitViewControllerDelegate> { 
    BOOL hasRun; 
} 

@property (nonatomic, assign) BOOL hasRun; 

MainViewController.m

@synthesize hasRun; 

-(void)viewDidLoad { 
    [super viewDidLoad]; 
    if (hasRun == 0) { 
     // Do some stuff 
     hasRun = 1; 
    } 
} 

¿Alguna idea?

+0

¿Usted ha intentado su código? – Jim

+0

¿Qué pasa con ejecutar '- (void) applicationDidFinishLaunching: (UIApplication *) application' o su código? O si no asigna su MainViewCOntroller, se ejecutará de todos modos – Seega

+1

una vez por _activation_ (es decir, una vez en el lanzamiento y nuevamente cuando vuelve del fondo), o una vez por vez, se carga en la memoria? –

Respuesta

72

Usted puede utilizar dispatch_once:

Objective-C

static dispatch_once_t once; 
dispatch_once(&once,^{ 
    NSLog(@"Do it once"); 
}); 

Swift

static var token: dispatch_once_t = 0 

dispatch_once(&token) { 
    NSLog("Do it once") 
} 
+2

+1; GCD es una opción más limpia para esta tarea que mantener un estado BOOL en su clase –

+23

Tenga en cuenta que esto es una vez por cada aplicación que se carga en la memoria. El código no se ejecutará nuevamente para otra instancia de esta clase que se está creando (esto me mordió recientemente), ni se ejecutará nuevamente cuando la aplicación vuelva a estar en primer plano desde la suspensión. –

+0

Gran respuesta. Esto se siente mucho más elegante que mi idea original. He aprendido algo ¡Gracias! –

7

No veo ningún problema con ese código. Me gusta usar un BOOL (como lo hizo) y luego asignar SÍ/NO o VERDADERO/FALSO solo para que el código se lea mejor. Asignaría TRUE a firstRun en didFinishLaunching, y lo configuraría FALSE después de que se ejecuta el código. En mi código de este tipo de condicionales por lo general se parece a esto:

@synthesize firstRun; 

-(void)viewDidLoad { 
    [super viewDidLoad]; 
    if (firstRun) { 
     // code to run only once goes here 
     firstRun = FALSE; 
    } 
} 
+0

La otra respuesta que recomienda Grand Central Dispatch es posiblemente un mejor enfoque. Por otro lado, como tecnología de nivel BSD, tiene una curva de aprendizaje bastante pronunciada considerando que esta es una pregunta "básica". Si desea hacer lo que ha pedido, este código es un poco más limpio que su original. Si desea probar un enfoque más avanzado para la administración de tareas, GCD es muy poderoso. – Dylan

-2

Con Swift2.0 , Xcode 7.0

var token: dispatch_once_t = 0 

override func viewDidLoad() { 
    super. viewDidLoad() 
    dispatch_once(&token) { 
     println("This is printed only on the first call to test()") 
    } 
    println("This is printed for each call to test()") 
} 
-2

para Swift2.2, Xcode 7.3:

static var token: dispatch_once_t = 0 

dispatch_once(&YourClassName.token) { 
    NSLog("Do it once") 
} 

Cuidado con "YourClassName.token"

Cuestiones relacionadas