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的线程模型有一些魔力。