Objective c 如何使方法暂停一段固定的时间?

Objective c 如何使方法暂停一段固定的时间?,objective-c,cocoa-touch,timer,Objective C,Cocoa Touch,Timer,我有一个应用程序,它调用一个有时快,有时慢的方法。我知道需要多长时间(2秒)的上限。我想设置一个计时器,在调用该方法时启动,运行代码,但直到2秒后才生成输出,不管实际需要多长时间。这样,用户会感觉到动作总是花费相同的时间。我如何实现这一点 我想要的是这样的东西: -(IBAction)doStuff { // START A TIMER, LOOK BUSY [activityIndicator startAnimating]; ... real work happens her

我有一个应用程序,它调用一个有时快,有时慢的方法。我知道需要多长时间(2秒)的上限。我想设置一个计时器,在调用该方法时启动,运行代码,但直到2秒后才生成输出,不管实际需要多长时间。这样,用户会感觉到动作总是花费相同的时间。我如何实现这一点

我想要的是这样的东西:

-(IBAction)doStuff {

  // START A TIMER, LOOK BUSY
  [activityIndicator startAnimating];

  ... real work happens here ...
  ... NSString *coolString gets assigned ...

  // WHEN TIMER == 2 SECONDS, REVEAL COOLNESS
  [activityIndicator stopAnimating];
  [textField setText:coolString];

}
应该有帮助

-(IBAction)doStuff {

  // START A TIMER, LOOK BUSY
  [activityIndicator startAnimating];

  ... real work happens here ...
  ... NSString *coolString gets assigned ...

  // WHEN TIMER == 2 SECONDS, REVEAL COOLNESS
[self performSelector:@selector(revealCoolnessWithString:) withObject:coolString afterDelay:2];

}

- (void)revealCoolnessWithString:(NSString *)coolString
{
[activityIndicator stopAnimating];
[textField setText:coolString];
}

希望这能有所帮助

有几种方法可以延迟Cocoa中的操作。最简单的方法可能是使用
性能选择器:withObject:afterDelay:
。此方法为您设置计时器,并在时间到来时调用指定的方法。这是一种
NSObject
方法,因此您的对象都可以免费获得它

这里棘手的部分是,第一个方法将阻止主线程,因此您需要将其放到后台线程上,然后返回主线程以更新UI。这里有一个尝试:

// Put the method which will take a while onto another thread
[self performSelectorInBackground:@selector(doWorkForUnknownTime)
                       withObject:nil];
// Delay the display for exactly two seconds, on the main thread
[self performSelector:@selector(displayResults)
           withObject:nil
           afterDelay:2.0];


我唯一能想到的另一件事是在
NSDate
中存储调用“work”方法的时间,并检查得到结果所用的时间。如果还不到两秒钟,请休眠后台线程,完成后再调用主线程

[self performSelectorInBackground:@selector(doWorkForUnknownTime:)
                       withObject:[NSDate date]];

-(void)工作时间未知:(NSDate*)开始时间{
//对于Cocoa,所有线程都必须有一个自动释放池。
@自动释放池{
//这需要一些时间
NSString*结果=…;//执行计算
NSTimeInterval elapsedTime=[[NSDate-date]timeIntervalSinceDate:startTime];
如果(延时<2.0){
//好吧,等一下,因为我们在后台线程上,
//虽然不理想,但休眠线程有点浪费。
//尽量不要经常这样做。
睡眠(2.0-延迟时间);
}
//不要忘记在主线程上保留结果!
[self-performSelectorOnMainThread:@selector(displayResults:)
withObject:结果
waitUntilDone:是的;
//[结果发布];//如有必要
}
}

睡眠(无符号秒)有效吗?@anon:在Cocoa中使用
睡眠
通常是错误的想法。@PengOne:它是一个C函数。它所做的一切就是暂停执行调用它的线程一段给定的秒数。我不知道为什么,但我不得不向上投票,因为代码中的第一条
//comment
哄骗了我一笑。然后我感觉很糟糕,因为我不能再次投票支持第二个。这里的大问题是,当“真正的工作”发生时,原始(大概是主)线程被阻塞(用户不能做任何事情)。这也是您不想使用
睡眠的原因。推迟执行是最容易的部分@BoltI在文档中没有看到
afterDelay
选项。它采用什么输入类型?选择器中有参数吗?如果是这样,请使用@selector(myfunc:)或者您可以使用:timer=[NSTimer scheduledTimerWithTimeInterval:0.001目标:自选择器:@selector(myfunc)userInfo:nil repeats:NO];我只是在我的代码中写了相同的(我首先建议的那个)。它工作得很好。@Nitish:这意味着我的方法只在2秒后开始。我希望开始到结束的时间正好是2秒。这很有帮助,但不能确保触发方法和显示结果之间的时间是2秒。它执行该方法,需要一些时间,然后等待2秒钟。将我的方法拆分以适应此框架需要一些时间,但这个想法看起来不错,我打赌它是有效的。不,该方法总共需要大约50行。不过,相关信息仍在那里。而且,分开也不难。这是有效的;谢谢@好的,很高兴我能帮忙!嘿,你刚刚让我超过5公里!谢谢我也是!我花了很长时间(>2秒)没有弄明白这一点:-)
- (void)doWorkForUnknownTime {

   // results is an ivar
   results = ...; // Perform calculations
}
- (void)displayResults {
    if( !results ){
        // Make sure that we really got results
        [self performSelector:@selector(displayResults:)
                   withObject:nil
                   afterDelay:0.5];
        return;
    }

    // Do the display!
}
[self performSelectorInBackground:@selector(doWorkForUnknownTime:)
                       withObject:[NSDate date]];
- (void)doWorkForUnknownTime:(NSDate *)startTime {

   // All threads must have an autorelease pool in place for Cocoa.
   @autoreleasepool{
       // This will take some time
       NSString * results = ...; // Perform calculations

       NSTimeInterval elapsedTime = [[NSDate date] timeIntervalSinceDate:startTime];
       if( elapsedTime < 2.0 ){
           // Okay to do this to wait since we're on a background thread, 
           // although not ideal; sleeping threads are kind of wasteful.
           // Try not to do this a lot.
           sleep(2.0 - elapsedTime);
       }

       // Don't forget to retain results on the main thread!
       [self performSelectorOnMainThread:@selector(displayResults:)
                              withObject:results
                           waitUntilDone:YES];
//     [results release];    // if necessary
    }
}