2012-03-05 2 views
21

У меня есть код, который я бы хотел запустить только один раз в моем MainViewController. Он должен запускаться каждый раз, когда пользователь запускает приложение, но только после загрузки MainViewController.Выполнение некоторого кода запускается только один раз

Я не хочу запускать его в -(void)applicationDidFinishLaunching:(UIApplication *)application.

Вот идея, которую я имел:

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

Есть идеи?

+0

Вы пробовали код? – Jim

+0

Что не так с запуском '- (void) applicationDidFinishLaunching: (UIApplication *) application' или ваш код? Или, если вы не назначили свой MainViewCOntroller, он будет запускаться один раз в любом случае – Seega

+1

Один раз за _activation_ (т. Е. Один раз при запуске и снова, когда он возвращается из фона), или один раз за время, когда он загружается в память? –

ответ

72

Вы можете использовать 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 - это более чистый выбор для этой задачи, чем сохранение состояния BOOL в вашем классе. –

+23

Обратите внимание, что это однократно загружается в приложение. Код не будет запущен снова для другого экземпляра создаваемого класса (этот бит мне недавно), и он не будет запущен снова, когда приложение вернется на передний план от приостановки. –

+0

Отличный ответ. Это кажется намного более элегантным, чем моя оригинальная идея. Я кое-что узнал. Благодаря! –

7

Я не вижу никаких проблем с этим кодом. Мне нравится использовать BOOL (как и вы), а затем назначая либо YES/NO, либо TRUE/FALSE, чтобы код читался более красиво. Я бы назначил TRUE для firstRun в didFinishLaunching и установил FALSE после выполнения кода. В моем коде этот тип условными обычно выглядит следующим образом:

@synthesize firstRun; 

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

Другой ответ, который рекомендует Grand Central Dispatch, возможно, является лучшим подходом. С другой стороны, в качестве технологии уровня BSD она имеет достаточно крутую кривую обучения, учитывая, что это «основной» вопрос. Если вы хотите делать то, что вы просили, этот код немного чище, чем ваш оригинал, - если вы хотите попробовать более продвинутый подход к управлению задачами, GCD очень эффективен. – Dylan

-2

С 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

для Swift2.2, Xcode 7.3:

static var token: dispatch_once_t = 0 

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

Берегись "YourClassName.token"

Смежные вопросы