Objective c 使某些代码只运行一次

Objective c 使某些代码只运行一次,objective-c,ios,Objective C,Ios,我有一些代码,我只想在MainViewController中运行一次。它应该在用户每次启动应用程序时运行,但只能在加载MainViewController之后运行 我不想在-(void)applicationdFinishLaunching:(UIApplication*)应用程序中运行它 以下是我的想法: MainViewController.h @interface IpadMainViewController : UIViewController <UISplitViewContro

我有一些代码,我只想在MainViewController中运行一次。它应该在用户每次启动应用程序时运行,但只能在加载MainViewController之后运行

我不想在
-(void)applicationdFinishLaunching:(UIApplication*)应用程序中运行它

以下是我的想法:

MainViewController.h

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

@property (nonatomic, assign) BOOL hasRun;

有什么想法吗?

我看不出这段代码有什么问题。我喜欢使用BOOL(正如您所做的那样),然后指定YES/NO或TRUE/FALSE,这样代码读起来就更好了。我会在didFinishLaunching中将TRUE指定给firstRun,并在代码执行后将其设置为FALSE。在我的代码中,这些类型的条件通常如下所示:

@synthesize firstRun;

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

Swift 1,2:

static var token: dispatch_once_t = 0

dispatch_once(&token) {
  NSLog("Do it once")
}
目标-C

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

Swift中不再提供dispatch_once。在Swift中,您可以使用 延迟初始化全局或静态属性,并获得相同的 线程安全和一次调用保证,如dispatch_once提供的


使用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()")
}

对于Swift2.2,Xcode 7.3:

static var token: dispatch_once_t = 0

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

注意“
YourClassName.token

由于在swift 3及以上版本中没有调度,我们可以使用惰性初始化全局变量

生成一个惰性全局变量

lazy var doOnlyOnce: () -> Void = {
    .. add code to run only once here ..
    return {}
}()
要运行代码,请执行以下操作:

_ = doOnlyOnce
可能的变化(Swift 5):


运行
-(void)applicationdFinishLaunching:(UIApplication*)application
或您的代码有什么问题?或者,如果您不分配MainViewCOntroller,则每次激活都会运行一次MainViewCOntroller(即,启动时运行一次,从后台返回时运行一次),或者每次加载到内存时运行一次?+1;对于这个任务来说,GCD比在类中维护BOOL状态更干净。注意,这是每个应用程序加载到内存中一次。该代码将不会在创建的这个类的另一个实例中再次运行(这是我最近写的),也不会在应用程序从暂停状态返回前台时再次运行。回答得很好。这感觉比我原来的想法优雅多了。我学到了一些东西。谢谢@JoshCaswell好的一点,你知道如何“重置”类的GCD或实例,以便在某个时候再次调用它吗?我可以调用
[[ClassName alloc]init]吗
来“重置”它?可以重置
一次
令牌@RazorSharp:,尽管在这一点上,我想说你应该使用另一种应该重置的机制,比如Dylan建议的
BOOL
属性。另一个建议Grand Central Dispatch的答案可以说是更好的方法。另一方面,作为BSD级技术,考虑到这是一个“基本”问题,它的学习曲线相当陡峭。如果你想按照你的要求去做,这段代码比你原来的代码稍微干净一点——如果你想尝试一种更高级的任务管理方法,GCD是非常强大的。
lazy var doOnlyOnce: () -> Void = {
    .. add code to run only once here ..
    return {}
}()
_ = doOnlyOnce
// Whether this is the first code run since app (re)started
var firstRun: Bool = true

public final class Foo {
    public init() {
        if firstRun {
            // Code that has to be run only once goes
            // HERE
            firstRun = false
        }
    }
}