多线程和一般层次理解

时间:2014-02-22 14:52:00

标签: iphone objective-c multithreading

每当我的应用程序变得有点复杂时,它就会达到视图不像我希望的那样快速刷新的程度。

例如,如果我有一个播放器按钮,并且每当用户点击该按钮时,按钮将改变其图像,然后播放器将播放一些音乐,图像需要很长时间才能改变。

无论图像更改后是否存在“SetNeedsdisplay”,或者即使用户“preformSelectorOnMainThred”更改图像,也会发生这种情况。

我添加了代码快照,显示了我的意思:

- (IBAction)playButtonPressed:(id)sender {


//This is the  image change, plus a small animation that should happen:
dispatch_async(dispatch_get_main_queue(), ^{

    [self.playButtonImage setImage:[UIImage imageNamed:@"PlayDiscButtonPressedMC"]];
    [[self superview] setNeedsDisplay];

    [self performSelector:@selector(animationInsertDisk) withObject:nil];

});

//This is the methus that will call the player to start playing, by delegate.
 [self performSelector:@selector(callDelegate) withObject:nil];;


}

发生的事情是,图像和动画的变化大约需要1-2秒才会发生,因为之后出现的是“callDelegate”!让我说我删除“callDelegate”然后图像和动画将发生在海峡之外!

我不明白为什么会发生这种情况,首先出现的代码是不是应该先发生? 是不是在主线程上发生了?

非常感谢任何帮助! 谢谢!!

1 个答案:

答案 0 :(得分:0)

我会尝试解释

dispatch_async计划块中的所有内容,以便将来使用。例如,如果您在按钮点按处理程序中调用dispatch_async,则在方法结束并将控件返回给系统之前,代码将不会执行。

[self performSelector:@selector(callDelegate) withObject:nil];

与写作相同

[self callDelegate];

这是一个简单的方法调用。这是一个阻塞电话。如果调用需要一些时间,那么UI中的所有内容都必须等待(因为您从UI线程调用它)。

您的代码基本上与以下内容相同:

- (IBAction)playButtonPressed:(id)sender {

    [self callDelegate];

    dispatch_async(dispatch_get_main_queue(), ^{
       [self.playButtonImage setImage:[UIImage imageNamed:@"PlayDiscButtonPressedMC"]];

       //no need for this here. Don't try to fix bugs by adding random code.
       //[[self superview] setNeedsDisplay];

       //performSelector just calls the method, so a direct call is exactly the same
       [self animationInsertDisk];
     });
}

现在,我不确定你想要通过dispatch_async实现什么。您希望动画立即启动,并且您已经在主线程上,所以只需执行

- (IBAction)playButtonPressed:(id)sender {
    [self.playButtonImage setImage:[UIImage imageNamed:@"PlayDiscButtonPressedMC"]];
    [self animationInsertDisk];

    [self callDelegate];
}

但是,“滞后”可能是由于您从主线程启动播放器并阻塞主线程一段时间。我不确定你在[self callDelegate]到底做了什么,但是dispatch_async包裹这个电话会有所帮助。