UIActionSheet需要很长时间才能做出回应

时间:2012-06-14 09:19:13

标签: iphone objective-c ios uiview uiactionsheet

我在actionSheet上创建UIActionSheet:clickedButtonAtIndex委托方法。

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex     
 if(buttonIndex == 1){

        [self.myFirstView removeFromSuperview]; 

        if (!self.mySecondView) {
            [[NSBundle mainBundle] loadNibNamed:@"MySecondView" owner:self options:nil];
        }
        [self.mySecondView setFrame:CGRectMake(0, 0, 320, 480)];

        [[UIApplication sharedApplication].keyWindow addSubview: self.mySecondView];

        UIActionSheet * action = [[UIActionSheet alloc]initWithTitle:@""
                                                            delegate:self
                                                   cancelButtonTitle: nil
                                              destructiveButtonTitle: deleteContacts
                                                   otherButtonTitles: cancel, nil];
        action.tag = 102;
        [action showInView:self.view];
        [action release];

    }

我使用与上面完全相同的方法处理此UIActionSheet的点击事件。

if(actionSheet.tag == 102){

    if(buttonIndex == 0){
        if([[NSBundle mainBundle] loadNibNamed:@"MyThirdView" owner:self options:nil]) { 
            [self.myThirdView setFrame:CGRectMake(0, 0, 320, 480)];
            [[UIApplication sharedApplication].keyWindow addSubview:self.myThirdView];
        }
        [self.mySecondView removeFromSuperview]; 

        [self.doneButton.target performSelector:self.doneButton.action withObject:self.doneButton.target];

        [self performSelector:@selector(RemoveView) withObject:self afterDelay:3.0];

    }
}

我面临的问题是,UIActionSheet需要花费太多时间来回应。当我点击UIActionSheet按钮时,它会在myThirdView加载之前处于冻结状态2或3秒。我无法理解,在这种情况下,响应延迟是什么,因为我在UIActionSheet按钮单击事件方法中首先要加载myThirdView。其余代码仅在加载myThirdView的代码之后执行。但即便是第一行代码似乎也会在延迟后执行。 有什么建议吗?

5 个答案:

答案 0 :(得分:3)

这可能是由于这个

[self performSelector:@selector(RemoveView) withObject:self afterDelay:3.0];

制作其他方法并在该方法中执行此操作。像这样

[self viewRemover];

并在viewRemover

-(void) viewRemover
{
    [self performSelector:@selector(RemoveView) withObject:self afterDelay:3.0];

}

所以你的代码现在就像这样

if(actionSheet.tag == 102){

    if(buttonIndex == 0){
        if([[NSBundle mainBundle] loadNibNamed:@"MyThirdView" owner:self options:nil]) { 
            [self.myThirdView setFrame:CGRectMake(0, 0, 320, 480)];
            [[UIApplication sharedApplication].keyWindow addSubview:self.myThirdView];
        }
        [self.mySecondView removeFromSuperview]; 

        [self.doneButton.target performSelector:self.doneButton.action withObject:self.doneButton.target];

    [self performSelectorInBackground:@selector(viewRemover) withObject:nil];

    }
}

答案 1 :(得分:3)

用户界面操作在主线程中运行,仅在方法结束时发生。因此,MyThirdView在其他说明完成之前不会显示。我唯一能想到的就是延迟:

[self.doneButton.target performSelector:self.doneButton.action withObject:self.doneButton.target];

如果您正在进行任何繁重的计算或净连接,请确定这就是原因。

OTOH,我认为你最好修改这一行:

[self.doneButton.target performSelector:self.doneButton.action withObject:self.doneButton];

如果你想模拟按键触摸动作。

答案 2 :(得分:2)

问题。 UIActionSheet是冻结还是消失,第3个视图在2-3秒内不可见?

这可能是由于2个问题中的1个。

  1. 如果整个操作表冻结,那么当您初始化第3个视图,加载某些核心数据或大量资产或需要花费很长时间的东西时,您正在做一些繁重的工作。如果是这种情况,您需要重新格式化如何加载第3个视图。我建议将任何重负载推到后台(这意味着如果你的xib中有很多图像,你可能需要在代码中加载它们。)

  2. 另一种可能性是,您是在第二个视图下面添加第三个视图,然后不会隐藏第二个视图3秒(通过延迟执行选择器完成)。如果是这种情况,只需删除延迟。

  3. 我做了几个课程来帮助我执行时间并找到代码中的瓶颈,看起来他们现在可以帮到你了。 http://forrst.com/posts/Code_Execution_Timer_for_iOS_Development-dSJ

答案 3 :(得分:1)

你的第三种观点有多大。如果nib文件需要加载太多,你可能会等待很多事情发生,如果你必须更改一些UI元素并阻止UI线程,你会骚扰你的应用程序,直到发生超时并且应用程序将转移有些事要补偿..

我采用的路线是dispatch_async和dispatch_sync

// This will release the UI thread which may be blocking your calls.
// You can use any of the DISPATCH_QUEUE_PRIORITY_.... values to set how important this block is.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
    // this command will get added to the stack and return without a hitch.
    // the block will be run the next time the main runloop ends.
    dispatch_async(dispatch_get_main_queue(), ^{
        // do some UI work that can happen without a hitch, and does not impact the calling block
    });

    // this command will act much the same. but will pause the background execution 
    // of this block until the runloop has executed this and returned.
    dispatch_sync(dispatch_get_main_queue(), ^{
        // do some UI work that must be completed to continue.
    });

});

在UI线程中执行太多操作会暂停执行堆积在队列中的事物。将所有代码发送到后台线程,只在需要更改UI时跳转到UI线程,这是一种更好,响应更快的方式来编写您的iPhone应用程序。

我希望这会有所帮助:)

答案 4 :(得分:0)

在Swift 4中: 我用这段代码包装了代码

requests.get('https://somewebsite.com', verify=False)

例如

DispatchQueue.main.async {

// your code to show action sheet.

}