开发者

How to run a code for only once?

开发者 https://www.devze.com 2023-02-21 02:33 出处:网络
I\'m working on an iPhone app, and I\'m wondering if I could run some code segment for only once (in other words: an initialization code, that I want it to be executed only at the very first run).

I'm working on an iPhone app, and I'm wondering if I could run some code segment for only once (in other words: an initialization code, that I want it to be executed only at the very first run). Here's my code, that I execute it at didFinishLaunchingwithOptions method:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    

// Override point for customization after application launch.

// Add the tab bar controller's view to the window and display.
[self.window addSubview:tabBarContr开发者_运维百科oller.view];
[self.tabBarController setSelectedIndex:2];
[self.window makeKeyAndVisible];

[self createPlist1];
[self createPlist2];
[self createPlist3];

return YES;

}

I want the last three messages to be executed only at the very first run. I thought I could use the UserDefaults and set a key after these messages executes (at the first run) and check for the value of that key at each run, but I'm feeling that there's a better idea -which I don't know.

Thanks in advance.


Using a setting (via NSUserDefaults) is how it's normally done. For added benefit, give the setting the meaning of "last run version"; this way, you'll get a chance to run code not only once per app lifetime, but also once per version upgrade.

That said, your run-once code has persistent side effects, right? Those plists go somewhere probably. So you can check if they exist before creating them. Use the result of the run-once code as a trigger for running it again.

EDIT:

NSUserDefaults *Def = [NSUserDefaults standardUserDefaults];
NSString *Ver = [Def stringForKey:@"Version"];
NSString *CurVer = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleVersionKey];
if(Ver == nil || [Ver compare:CurVer] != 0)
{
    if(Ver == nil)
    {
        //Run once per lifetime code
    }
    //Run once-per-upgrade code, if any
    [Def setObject:CurVer forKey:@"Version"];
}


A much simpler possible solution ->

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if ([defaults objectForKey:@"FirstTimeBool"]==nil)
{
    [defaults setObject:@"YES" forKey:@"FirstTimeBool"];
    ... //Code to be executed only once until user deletes the app!
    ...


this is what I used:

static dispatch_once_t once;

dispatch_once(&once, ^ { 

    // run once code goes here

});


I think you're on the right track with the User Defaults, something like:

-(BOOL)isInitialRun
{
     NSNumber *bRun = [[NSUserDefaults standardUserDefaults] valueForKey:@"initialRun"];
     if (!bRun) { return YES; }
     return [bRun boolValue];
}

-(void)setIsInitialRun:(BOOL)value
{
     [[NSUserDefaults standardUserDefaults] setBool:value forKey:@"initialRun"];
}

Then in your app delegate:

if ([self isInitialRun])
{
     [self createPlist1];
     [self createPlist2];
     [self createPlist3];
     [self setIsInitialRun:NO];
}


To my knowledge, the way you propose is the only option. Save a key to NSUserDefaults after you ran it for the first time and check for the existence of said key.
You could however, also check in each of your functions (the createPlist1 - 3 functions) run a check if the PList is already there. Would be a bit cleaner.


One thing I would add to @Seva Alekseyev answer:

After you make any changes (i.e. [Def setObject:CurVer forKey:@"Version"];) you should call [Def synchronize]

I had a problem where changes made to NSUserDefaults using setObject were not getting saved, until I used synchronize.

0

精彩评论

暂无评论...
验证码 换一张
取 消