神秘的UIActivityIndi​​catorView错误?

时间:2015-08-10 23:12:41

标签: ios xcode swift error-handling exc-bad-access

当我在应用程序中执行特定操作时,我一直收到EXC_BAD_ACCESS错误/崩溃。认为这是一个内存管理问题,我让NSZombies帮我解释这个问题。崩溃后,我的控制台给了我以下信息:

enter image description here

继承我的堆栈跟踪:

enter image description here

并突出显示我的app委托行的新错误:

enter image description here

现在调试器是指UIActivityIndi​​catorRelease,我的堆栈跟踪中突出显示的唯一代码行是我的委托中的第一行,我的Activity Indicator UI Element是否存在问题?这是我的登录操作中的逻辑(每次强制崩溃):

@IBAction func Login(sender: AnyObject) {

        activityIND.hidden = false
        activityIND.startAnimating()

        var userName = usernameText.text
        var passWord = passwordText.text

        PFUser.logInWithUsernameInBackground(userName, password: passWord) {
            (user, error: NSError?) -> Void in
            if user != nil {

                dispatch_async(dispatch_get_main_queue()) {
                    self.performSegueWithIdentifier("loginSuccess", sender: self)
                }

            } else {
                self.activityIND.stopAnimating()

                if let message: AnyObject = error!.userInfo!["error"] {
                    self.message.text = "\(message)"
                }
            }
        }
    }

里面有错误吗?

3 个答案:

答案 0 :(得分:2)

绝对正确操作UI对象的所有代码必须从主线程完成。 (正如@JAL在评论中所说的那样,它应该在dispatch_async(dispatch_get_main_queue())的电话中。

这不仅包括self.activityIND.stopAnimating()行,还包括设置标签文本的代码(任何操作UIKit对象的代码,如UIView)。

你的if ... else子句看起来像这样:

if user != nil 
{
  dispatch_async(dispatch_get_main_queue()) 
  {
    self.activityIND.stopAnimating()
    self.performSegueWithIdentifier("loginSuccess", sender: self)
  }
}
else 
{
  dispatch_async(dispatch_get_main_queue()) 
  {
    self.activityIND.stopAnimating()
    if let message: AnyObject = error!.userInfo!["error"] 
    {
      self.message.text = "\(message)"
    }
  }
}

答案 1 :(得分:0)

事实证明,在我viewDidLoad()中,我有以下代码试图隐藏负载上的指标:

UIActivityIndicator.appearance().hidden = true UIActivityIndicatorView.appearance().hidesWhenStopped = true

不知道这会释放应用程序其余部分的指示符,所以当我在登录逻辑中调用以下内容时:

activityIND.hidden = false

activityIND.startAnimating()

我正在向一个不再可用的实例发送消息,导致崩溃。所以我所做的就是调整viewDidLoad()中的代码 致:

activityIND.hidden = true

activityIND.hidesWhenStopped = true

使用我创建的特定插座的名称而不是通用UIActivityIndicatorView

答案 2 :(得分:0)

所有与UI相关的操作都应在主线程中执行,即在

中执行
  

dispatch_async(dispatch_get_main_queue(){}

@IBAction func Login(sender: AnyObject) {

        activityIND.hidden = false
        activityIND.startAnimating()

        var userName = usernameText.text
        var passWord = passwordText.text

        PFUser.logInWithUsernameInBackground(userName, password: passWord) {
            (user, error: NSError?) -> Void in
            if user != nil {

                dispatch_async(dispatch_get_main_queue()) {
                    self.performSegueWithIdentifier("loginSuccess", sender: self) //UI task
                }

            } 
            else {
                dispatch_async(dispatch_get_main_queue()) 
               {
                 self.activityIND.stopAnimating() //UI task
                 if let message: AnyObject = error!.userInfo!["error"] 
                 {
                   self.message.text = "\(message)" //UI task
                  }
                 };
            }
        }
    }

请参阅有关并发herehere

的一些好文章