【问题标题】:Executing methods one after another with pauses between executing一个接一个地执行方法,执行之间有停顿
【发布时间】:2012-11-14 09:11:03
【问题描述】:

新手 obj-c 问题。 我正在为 Appstore 编写一个简单的 iPad 演示文稿。我的任务是实现几个方法一个接一个地执行,它们之间几乎没有停顿。主要结构如下:

  • 查看负载
  • 暂停两秒,然后执行method1
  • 暂停两秒,然后执行method2
  • 暂停两秒,然后执行method3 等等……

我从 -viewDidLoad 调用的第一个方法:

NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(firstCountStarts) userInfo:nil repeats:NO];

这里一切正常,方法在视图加载后 2 秒开始。 从method1内部,我尝试以相同的方式调用方法2,但它开始与method1同时执行。同样的方式触发了method3(从method2调用)和它们之后的所有方法都没有执行。我试图将所有这些方法放在 -ViewDidLoad 中并延迟调用它们:

 [self method1];
 [self performSelector:@selector(method2) withObject:nil afterDelay:2];
 [self performSelector:@selector(method3) withObject:nil afterDelay:4];
 etc...

但是在method2调用之后所有的方法都没有执行。如果我正确理解线程中的问题。我需要使用 GCD 来执行不同队列中的方法吗?或者其他方面的问题?

谢谢各位同事!

【问题讨论】:

    标签: iphone objective-c ios xcode method-call


    【解决方案1】:

    您可以将这些添加到 NSOperation 队列中...

    NSOperationQueue *queue = [NSOperationQueue new];
    
    queue.maxConcurrentOperationCount = 1;
    
    [queue  addOperationWithBlock:^{
        [self method1];
    }];
    
    [queue  addOperationWithBlock:^{
        [NSThread sleepForTimeInterval:2.0];
        [self method2];
    }];
    
    [queue  addOperationWithBlock:^{
        [NSThread sleepForTimeInterval:2.0];
        [self method3];
    }];
    
    ...
    

    这将仅在前一个完成后运行每个,并为您设置 2 秒的延迟。

    小心使用它来做 UI 的东西。这将在后台线程中运行,因此您可能需要处理它。

    也许这可能会更好,你可以通过子类化 NSOperation 来做到这一点,但这是很多工作却没有多大好处。

    从你想要的任何地方运行它,我建议将所有这些放入一个名为 setUpQueue 的函数中。

    然后从 viewWillAppear 或 viewDidLoad 或其他地方,按下按钮等...做...

    [self setUpQueue];
    

    您所要做的就是将内容添加到队列中,然后队列将自行管理。

    【讨论】:

    • 我只是在这里尝试了这段代码,因为我可以在我的项目中使用类似的东西。但是由于某种原因,块内的选择器没有被调用。他们有什么理由不工作吗?如果我只调用方法本身就可以正常工作,但在选择器方法内部永远不会被调用
    • 啊,刚刚想到,performSelectorWithDelay 会将它撞到另一个线程上。可以试试别的...
    • NSTimer 代替 performSelectorWithDelay?
    • 在块内部,您不能使用任何将线程推到 BG 线程的东西,因为这将完成操作。每个操作都必须同步运行。您不能使用 NSTimer 或 performSelectorWithDelay 等...
    • 它不是很优雅,但你可以使用 +[NSThread sleepForTimeInterval:] 这应该可以。
    【解决方案2】:

    您可以使用单个计时器,并按照您想要执行的顺序围绕您想要执行的方法编写一个 switch 语句。例如

    int turn = 0;
    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(runmethod) userInfo:nil repeats:NO];
    

    然后在运行方法中

    switch(turn)
    {
      case 0:
            // do method 1 stuff
            ++turn;
            break;
      case 1:
            // do method 2 stuff
            ++turn;
            break;
        .
        .
        .
    }
    
    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(runmethod) userInfo:nil repeats:NO];
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-02
      • 2023-02-11
      • 1970-01-01
      • 1970-01-01
      • 2013-12-22
      • 2018-03-30
      相关资源
      最近更新 更多