performSelector:withObject:afterDelay:不打电话

在一个方法中,我想在n秒后调用一个方法:

self.toolBarState = [NSNumber numberWithInt:1]; [self changeButtonNames]; [self drawMap]; [self performSelector:@selector(showActionSheet) withObject:nil afterDelay:2]; 

我想在drawMap完成2秒后显示动作表。 当我使用这个performSelector,它永远不会打电话。

如果我只是把[自我showActionSheet],它工作得很好。 有没有原因为什么performSelector不拨打电话?

编辑:在我的代码的另一部分,我做了同样的电话,它的工作原理:

 HUD = [[MBProgressHUD alloc] initWithView:self.view]; [self.view addSubview:HUD]; HUD.delegate = (id) self; [HUD showWhileExecuting:@selector(drawMap) onTarget:self withObject:nil animated:YES]; [self performSelector:@selector(showActionSheet) withObject:nil afterDelay:6]; 

这里showActionSheet在drawMap完成后的6秒内被调用。 我猜测有线程,我不明白的东西正在进行…

EDIT2:

 -(void)showActionSheet { InspectAppDelegate *dataCenter = (InspectAppDelegate *) [[UIApplication sharedApplication] delegate]; if (dataCenter.fieldIDToPass == nil) { UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:@"Selected Boundary Options" delegate:(id) self cancelButtonTitle:@"Cancel" destructiveButtonTitle:nil otherButtonTitles:@"Analyze a Field",@"Retrieve Saved Analysi", @"Geotag Photos", @"Refresh the map",nil]; actionSheet.tag = 0; [actionSheet showInView:self.view]; } else { UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:@"Selected Boundary Options" delegate:(id) self cancelButtonTitle:@"Cancel" destructiveButtonTitle:nil otherButtonTitles:@"Analyze a Field",@"Retrieve Saved Analysi", @"Geotag Photos", @"Attribute the Field", @"Refresh the map",nil]; actionSheet.tag = 0; [actionSheet showInView:self.view]; } } 

EDIT3:

好的,所以方法调用的进度是:

 -(void) foundDoubleTap:(UITapGestureRecognizer *) recognizer { [HUD showWhileExecuting:@selector(select) onTarget:self withObject:nil animated:YES]; } -(void) select { [self changeButtonNames]; [self drawMap]; [self performSelector:@selector(showActionSheet) withObject:nil afterDelay:2]; } 

showActionSheet永远不会被调用。 就像我说的,我很确定它是一个线程问题。 如果用[self showActionSheet]调用它,它将运行。 = /

尝试使用 –

  -(void) select { [self changeButtonNames]; [self drawMap]; [self performSelectorOnMainThread:@selector(showActionSheet) withObject:nil waitUntilDone:YES]; } 

-performSelector:withObject:afterDelay:调度同一个线程上的定时器,在传递的延迟后调用select器。

可能是你的这个工作 –

 -(void) select { [self changeButtonNames]; [self drawMap]; [self performSelectorOnMainThread:@selector(someA) withObject:nil waitUntilDone:YES]; } -(void)someA { [self performSelector:@selector(showActionSheet) withObject:nil afterDelay:2]; } 

我遇到了同样的问题,而且我必须解决它与接受的答案略有不同。 注意我想要我的延迟和select器是variables? 使用块允许我保持在我目前的方法。

 dispatch_async(dispatch_get_main_queue(), ^{ [self performSelector:loopSelector withObject:nil afterDelay:cycleTime]; }); 

顺便说一句,这绝对是一个线程问题。 performSelector的文档:withObject:afterDelay:指出这将在延迟后在当前线程上执行,但有时该线程的运行循环不再处于活动状态。

关于这个问题的更详细的讨论可以在这里find

你的课是否还在内存中?

如果你的课程在performSelector触发前就消失了,你会发送消息给nil (这不会导致任何事情发生)。 你可以通过将NSLog放入你的dealloc()

你提到了线程。 如果您的performSelector没有从MainThread调用它可能会导致问题(UI的东西应该在主线程上完成)。

当我调用performSelector:withObject:afterDelay:在由ReactiveCocoa创build的后台线程中时,我得到了同样的问题。 如果我以ReactiveCocoa的方式执行块,块将被正确调用:

  [[[RACSignal empty] delay:2.0] subscribeCompleted:^(){ // do something }]; 

我想ReactiveCocoa的线程模型有一些魔力。