当我在应用程序中执行特定操作时,我一直收到EXC_BAD_ACCESS错误/崩溃。认为这是一个内存管理问题,我让NSZombies帮我解释这个问题。崩溃后,我的控制台给了我以下信息:
继承我的堆栈跟踪:
并突出显示我的app委托行的新错误:
现在调试器是指UIActivityIndicatorRelease,我的堆栈跟踪中突出显示的唯一代码行是我的委托中的第一行,我的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)"
}
}
}
}
里面有错误吗?
答案 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 } }; } } }的一些好文章