DismissViewController有时会导致程序冻结或崩溃

时间:2012-03-23 06:11:04

标签: c# ios xamarin.ios

我有以下MonoTouch程序:

using System.Drawing;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
using System;

namespace Experiment
{
    // This is just for the example, I use a singleton in my app to do this.
    public class AppSettings
    {
        public static bool IsLoggedIn = false;
    }

    [Register ("AppDelegate")]
    public class AppDelegate : UIApplicationDelegate
    {
        UIWindow window;
        public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
        {
            UIViewController baseViewController = new RootViewController();

            window = new UIWindow(UIScreen.MainScreen.Bounds);
            window.AddSubview(baseViewController.View);
            window.MakeKeyAndVisible();

            return true;
        }

        static void Main(string[] args)
        {
            UIApplication.Main(args, null, "AppDelegate");
        }
    }

    public class RootViewController : UITableViewController
    {
        public override void ViewDidAppear(bool animated)
        {
            base.ViewDidAppear(animated);
            if (!AppSettings.IsLoggedIn) {
                this.PresentViewController(new LoginPopupController(), false, () => {});
            }

        }
    }

    public class LoginPopupController : UIViewController
    {
        public override void LoadView()
        {
            View = new UIView(UIScreen.MainScreen.ApplicationFrame);
            View.BackgroundColor = UIColor.White;

            UIButton button = new UIButton();
            button.SetTitle("press me", UIControlState.Normal);
            button.Frame = new RectangleF(50, 50, 80, 80);
            button.TouchUpInside += delegate {
                LoginSucceeded();
            };
            button.BackgroundColor = UIColor.Purple;
            View.AddSubview(button);
        }


        public void LoginSucceeded()
        {
            AppSettings.IsLoggedIn = true;
            Console.WriteLine("This line causes multiple problems at random");
            DismissViewController(true, () => {});

        }
    }
}

它有两个控制器RootViewController和LoginPopupController。 FinishedLoading方法将RootViewController添加到窗口。 ViewDidAppear方法中的RootViewController检查应用程序是否已登录。如果没有,它将显示LoginPopupController。

LoginPopupController有一个按钮,按下后会将IsLoggedIn设置为true,并自行关闭。

基本上,如果用户未登录,我想要一个登录窗口,然后在将登录详细信息输入到单例设置对象后自行解除。


然而,此应用程序目前非常不可靠。按“按我”按钮可以导致以下情况随机发生:

  • 按预期工作
  • 冻结应用
  • 崩溃应用
  • 首次按下时不执行任何操作,第二次按下时应用程序崩溃

Console.WriteLine行对此有很大影响 - 如果删除它,代码会更频繁地成功(但并非总是如此)。

任何人都可以找出造成这个问题的原因吗?这似乎是一种竞争条件(因为结果在运行之间发生了变化),但是我无法弄清楚可能导致这种情况的原因。

我正在使用iOS 5.1在模拟器上运行代码。我在Mono 2.10.8上安装了MonoTouch 5.2.10版。

1 个答案:

答案 0 :(得分:2)

我在你的代码中做了两处更改,它从未崩溃,至少在我的尝试次数上是这样。

首先,将UIButton声明移至课程:

UIButton button;
public override LoadView()
{
  //...
}

其次,使用UIButton.FromType(UIButtonType)静态方法初始化按钮:

button = UIButton.FromType(UIButtonType.Custom);

UIButton()构造函数在以前版本的MonoTouch中存在问题。在某些版本中它甚至不可用。根据Apple文档,我无法找到任何特定于其当前状态的内容,但是使用静态方法创建按钮是正常的方法。