如何只运行一次代码?

时间:2011-03-29 16:41:54

标签: iphone objective-c cocoa-touch xcode

我正在研究iPhone应用程序,我想知道我是否只能运行一次代码段(换句话说:初始化代码,我希望它只在第一次运行时执行) 。 这是我的代码,我在didFinishLaunchingwithOptions方法执行它:

- (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:tabBarController.view];
[self.tabBarController setSelectedIndex:2];
[self.window makeKeyAndVisible];

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

return YES;

}

我希望最后三条消息仅在第一次运行时执行。我想我可以使用UserDefaults并在这些消息执行后设置一个键(在第一次运行时)并在每次运行时检查该键的值,但我觉得有一个更好的主意 - 我不知道

提前致谢。

6 个答案:

答案 0 :(得分:11)

使用设置(通过NSUserDefaults)是通常的做法。为了增加好处,请设置“最后运行版本”的含义;这样,您将有机会不仅每个应用程序生命周期运行一次代码,而且每次版本升级也运行一次。

那就是说,你的一次性代码有持久的副作用,对吧?那些钳子可能会去某个地方。因此,您可以在创建它们之前检查它们是否存在。使用一次性运行代码的结果作为再次运行它的触发器。

编辑:

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

答案 1 :(得分:3)

一个更简单的可能解决方案 - >

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!
    ...

答案 2 :(得分:2)

我认为你的用户默认值是正确的,例如:

-(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"];
}

然后在你的app delegate:

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

答案 3 :(得分:2)

这就是我使用的:

static dispatch_once_t once;

dispatch_once(&once, ^ { 

    // run once code goes here

});

答案 4 :(得分:1)

据我所知,你提出的方式是唯一的选择。首次运行后,将密钥保存到NSUserDefaults并检查是否存在所述密钥 但是,你也可以检查你的每个函数(createPlist1 - 3函数)运行检查PList是否已经存在。会有点干净。

答案 5 :(得分:0)

我要补充一点@Seva Alekseyev回答:

进行任何更改后(例如[Def setObject:CurVer forKey:@"Version"];),您应致电[Def synchronize]

我遇到一个问题,在使用了同步之前,使用setObject对NSUserDefaults进行的更改没有得到保存。

相关问题