是否有可能performSelector:withObject:afterDelay:在子线程中不工作?
我对目标C和Xcode还不熟悉,所以我可能遗漏了一些显而易见的东西./我真的很想得到一些帮助。
我所要做的就是用3秒的时间展示一个字母,然后它就会被隐藏起来。如果设置了新信息,3秒后隐藏标签的线程将被取消。(我不希望旧线程隐藏新信息。)
Sourcecode:
- (void) setInfoLabel: (NSString*) labelText
{
// ... update label with text ...
infoLabel.hidden = NO;
if(appDelegate.infoThread != nil) [appDelegate.infoThread cancel]; // cancel last hide-thread, if it exists
NSThread *newThread = [[NSThread alloc] initWithTarget: self selector:@selector(setInfoLabelTimer) object: nil];// create new thread
appDelegate.infoThread = newThread; // save reference
[newThread start]; // start thread
[self performSelector:@selector(testY) withObject: nil afterDelay:1.0];
}
-(void) setInfoLabelTimer
{
NSLog(@"setInfoLabelTimer");
[self performSelector:@selector(testX) withObject: nil afterDelay:1.0];
[self performSelector:@selector(hideInfoLabel) withObject: nil afterDelay:3.0];
NSLog(@"Done?");
}
-(void) testX
{
NSLog(@"testX testX testX testX testX");
}
-(void) testY
{
NSLog(@"testY testY testY testY testY");
}
-(void) hideInfoLabel
{
NSLog(@"f hideInfoLabel");
if(!([[NSThread currentThread] isCancelled])) {
AppDelegate *appDelegate = (AppDelegate *) [[UIApplication sharedApplication] delegate];
appDelegate.infoThread = nil;
appDelegate.infoLabel.hidden = YES;
[NSThread exit];
}
}Console-Output:
如您所见,performSelector:withObject:afterDelay:确实工作(-->“testY testY"),但在子线程(运行(-->”setInfoLabelTimer“和”Done?“))中不起作用。
有人知道为什么performSelector:withObject:afterDelay:在子线程中不工作吗?(或者我的错是什么?)
向你问好,茶壶
发布于 2013-06-25 14:04:33
发布于 2013-06-25 13:29:40
顺便提一下,您可能想考虑使用中央调度、GCD。如果你想在三秒钟内完成某件事,你可以:
double delayInSeconds = 3.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
// do stuff here, and because it's in the main queue, you can do UI stuff, too
});我还将在并发编程指南中向您推荐从线程迁移。
或者,与使用GCD不同,您可以使用一个动画块,在该块中,您可以指定您希望在3.0秒内发生的事情。您还可以激活该转换(在我的示例中是0.25秒),这样删除控件就更优雅了:
[UIView animateWithDuration:0.25
delay:3.0
options:0
animations:^{
// you can, for example, visually hide in gracefully over a 0.25 second span of time
infoLabel.alpha = 0.0;
}
completion:^(BOOL finished) {
// if you wanted to actually remove the view when the animation was done, you could do that here
[infoLabel removeFromSuperview];
}];发布于 2013-06-25 13:30:40
如果您正在运行一个“子”线程(一个不是主线程的线程),它可以以以下两种方式之一运行:
如果线程以表单1运行,那么使用performSelector将一个项放入队列(或至少尝试),但它永远不会被处理,线程就会终止。
如果您想在线程上使用performSelector,那么您需要做额外的工作。或者,您可以将该项推送到正在运行run循环的主线程上。
https://stackoverflow.com/questions/17297595
复制相似问题