【问题标题】:Showing Waiting Alert View At Load在加载时显示等待警报视图
【发布时间】:2014-01-13 15:40:06
【问题描述】:

我希望当我的应用启动时,它会显示大约 5 秒的警报视图,然后根据后台进程的结果,它会显示另一个警报视图。

我遇到的问题是,当我尝试使用睡眠等待后台进程发生时。第一个警报不显示并等待 5 秒。该应用程序显示应用程序的第一个视图,然后在 5 秒后短暂显示第一个警报。

我需要做什么来完成我的愿望。

这是我的代码。

- (void)viewDidAppear:(BOOL)animated
{
    SSGlobalSettings *connSettings = [SSGlobalSettings sharedManager];

    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Connecting" message:@"Please wait, while your device connects" delegate:Nil cancelButtonTitle:nil otherButtonTitles: nil];
    [alertView show];

    [NSThread sleepForTimeInterval:5.0f];

    [alertView dismissWithClickedButtonIndex: alertView.cancelButtonIndex animated: YES];

    if ([connSettings.connectionStatus  isEqual: @"Not Found"])
    {
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Connection Failed" message:@"Cannot find your device on the network" delegate:Nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
        [alertView show];
    }
    else
    {
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Connection Success" message:@"WYour device has been found on the network" delegate:@"OK" cancelButtonTitle:nil otherButtonTitles: nil];
        [alertView show];
    }
}

【问题讨论】:

  • 因为您将警报设置为在另一个线程上运行,而不是在 UIAlertView 将运行的主线程上。要让主线程休眠,只需调用sleep(5)
  • 完全相同的结果。我相信 [NSThread sleepForTimeInterval:5.0f] 确实阻塞了同一个 UI 线程。好吧,它在这里声明-stackoverflow.com/questions/2232366/…
  • 正如DuncanC 所说,无论如何你都不应该阻塞主线程。我什至不建议使用 sleep(5); 这就是为什么我没有将其添加为答案。

标签: ios objective-c alert wait cocoaasyncsocket


【解决方案1】:

不要在主线程上使用睡眠。曾经。也不要从后台线程更新 UI。

您要做的是在主线程上显示警报并返回。

然后,当您的网络代码完成时,让它向主线程发送一条消息。在主线程中,当您收到通知已完成时,请删除警报。

【讨论】:

    【解决方案2】:

    它无法正常工作,因为您试图让应用程序的主线程进入睡眠状态。如果您要让该线程休眠,那么您很可能不允许在此期间发生任何 UI 更新,因为所有 UI 更新都发生在主线程上。

    您需要做的是将显示第二个 UIAlertView 的代码移动到第二个方法,然后调用方法 - (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay,将第二个方法传递给选择器,并给它 5 秒的延迟。确保你移除了睡眠主线程的调用。

    但是,这似乎仍然是一种不好的做法,因为此操作应该是在后台任务完成后发生的。因此,如果可以的话,您应该运行代码以在完成该任务时显示第二个警报视图,该任务很可能会在不同的时间内完成。

    【讨论】:

    • 是的,我确实首先尝试让它执行依赖于后台任务完成的操作。但这是由于对异步发生的网络广播数据包的响应而发生的。它在另一个线程上。此外,我试图避免在我的网络连接代码中包含 UI 代码。因此,我改为更新应用程序在整个过程中使用的共享值来确定连接状态。
    • 您可以使用- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait,指定主线程,使其在主线程上执行。您也可以使用 Grand Central Dispatch,这将是首选方式。但是仅仅有一个硬编码的延迟似乎是一个非常糟糕的主意,并且由于网络请求的完成而发生 UI 更改是标准的。如果你想把事情分开,你可以为你的网络连接代码制作你自己的委托协议,这样你的 UI 代码就可以和你的 UI 代码的其余部分保持一致。
    • 感谢 Gavin,当我没有收到来自网络的响应时,我该怎么办。我的应用程序发送了一个广播数据包,它要求设备以“嘿,我在这里”数据包进行响应。但如果设备不存在,我的应用程序不会收到任何数据包。所以我需要在一段时间后等待或超时。所以我的用户可以执行另一个操作。
    • 现在会发生什么?您的网络代码中是否已经存在超时?您可以指定您选择的超时时间吗?如果您可以指定超时,请为用户选择合理的等待时间(以确保如果存在,您将及时收到响应),并为您的网络代码设置一个委托协议,该协议具有委托方法成功与失败。然后在您的 UI 代码中实现这些方法,并将其作为您的网络代码的委托。您应该能够以这种方式轻松处理成功和失败的两种情况。
    • 我的代码没有超时。我要么收到回复,要么没有收到回复。基本上,它将接收响应的 UDP 侦听器。响应返回通常需要不到一秒钟的时间。我正在使用 CoacaAsyncSockets - github.com/robbiehanson/CocoaAsyncSocket 。我不相信有任何可用的超时功能。我可以启动另一个超时线程,然后调用 performSelector。
    【解决方案3】:

    你以你的方式阻塞了主线程。

    我认为您似乎只是希望用户在前 5 秒之前不要做任何事情(让您连接成功?),如果是这样,有很多方法可以做到这一点,例如只需在窗口顶部显示一个视图,直到您希望用户可以做某事,您可以在该视图上显示消失按钮或立即将其消失。

    【讨论】:

    • 是的,这就是我正在做的事情。我的应用程序向设备发送一个 UDP 广播数据包,然后该设备以有关其自身的信息进行响应。如果找到设备,则使用此信息更新共享值,如果未找到,则此共享值保持为“未找到”。
    • 如果是这样,我认为使用警报视图,这是一种不好的方法,您可以轻松覆盖所有 ui 上的视图,然后用户只能在此视图上进行一些交互,也许您可​​以输入一个等待动画让用户耐心等待。直到你连接成功,发布一个通知,让你等待视图捕捉到这个通知,然后消失这个视图让用户知道你连接成功!
    • 大部分情况下,连接成功后dev会发布通知,这样便于控制应用,请注意在主线程发布通知,以便在收到此通知时可以做一些ui工作,否则你应该分派到主线程来更新用户界面
    • 我的情况是我正在发送广播数据包,即询问我的硬件设备是否在网络上。如果设备不在网络上,则不会收到任何响应。所以我需要某种等待或超时功能,所以如果设备没有响应,我可以向用户提供详细信息。
    【解决方案4】:

    您可以改用 performSelector:withObject:afterDelay: 方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-08
      • 2015-07-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多