2012-03-05 13 views
21

Mam kod, który chciałbym uruchomić tylko raz w moim MainViewController. Powinien być uruchamiany za każdym razem, gdy użytkownik uruchamia aplikację, ale dopiero po załadowaniu MainViewController.Dokonywanie kodu uruchamia się tylko raz

Nie chcę go uruchomić w -(void)applicationDidFinishLaunching:(UIApplication *)application.

Oto pomysł miałem:

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; 
    } 
} 

pomysłów?

+0

Czy próbowałeś kod? – Jim

+0

Co jest nie tak z uruchomieniem '- (void) applicationDidFinishLaunching: (UIApplication *) application' lub twój kod? Lub jeśli nie przydzielisz swojego MainViewCOntroller, zostanie on uruchomiony raz i tak – Seega

+1

Raz na _activation_ (tj. Raz przy uruchomieniu i ponownie, gdy powraca z tła), lub raz na raz zostanie załadowany do pamięci? –

Odpowiedz

72

Można użyć 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 jest czystszym wyborem dla tego zadania niż utrzymywanie stanu BOOL w twojej klasie. –

+23

Pamiętaj, że jest to raz dla aplikacji ładowanej do pamięci. Kod nie zostanie uruchomiony ponownie dla innej instancji tej klasy, która jest tworzona (ostatnio to mnie bit), ani nie będzie uruchamiana ponownie, gdy aplikacja powróci na pierwszy plan z zawieszenia. –

+0

Świetna odpowiedź. Jest to o wiele bardziej eleganckie niż mój pierwotny pomysł. Nauczyłem się czegoś. Dzięki! –

7

Nie widzę problemu z tym kodem. Lubię używać BOOL (tak jak ty), a następnie przypisujesz YES/NO lub TRUE/FALSE tylko po to, aby kod ładniej się ładował. Przypisałbym TRUE do firstRun w didFinishLaunching i ustawiłem FALSE po wykonaniu kodu. W moim kodu Tego typu warunkowych zazwyczaj wygląda tak:

@synthesize firstRun; 

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

Inna odpowiedź, która zaleca Grand Central Dispatch, jest prawdopodobnie lepszym podejściem. Z drugiej strony, jako technologia na poziomie BSD ma dość stromą krzywą uczenia się, biorąc pod uwagę, że jest to "podstawowe" pytanie. Jeśli chcesz zrobić to, o co prosiłeś, ten kod jest nieco bardziej czysty od oryginału - jeśli chcesz spróbować bardziej zaawansowanego podejścia do zarządzania zadaniami, GCD jest bardzo potężny. – Dylan

-2

Z 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

dla Swift2.2, Xcode 7.3:

static var token: dispatch_once_t = 0 

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

Uważaj "YourClassName.token"

Powiązane problemy