神秘的 UIActivityIndicatorView 错误?
mysterious UIActivityIndicatorView error?
当我在我的应用程序中执行特定操作时,我一直收到 EXC_BAD_ACCESS error/crash。确定这是一个内存管理问题,我启用了 NSZombies 来帮助我破译这个问题。崩溃后,我的控制台给了我以下消息:
这是我的堆栈跟踪:
以及突出显示我的应用委托行的新错误:
现在调试器指的是 UIActivityIndicatorRelease,我的堆栈跟踪中唯一突出显示的代码行是我的委托中的第一行,我的代码有问题吗Activity 指标 UI 元素?这是我的登录操作中的逻辑(每次都会强制崩溃):
@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)"
}
}
}
}
里面有没有错误?
所有绝对、肯定地操作 UI 对象的代码都必须从主线程完成。 (因此,正如@JAL 在他的评论中所说,它应该在对 dispatch_async(dispatch_get_main_queue())
的调用中。
这不仅包括 self.activityIND.stopAnimating()
行,还包括设置标签文本的代码(任何像 UIView 一样操作 UIKit 对象的代码)。
您的 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)"
}
}
}
事实证明,在我的 viewDidLoad()
中,我有以下代码试图隐藏负载上的指示器:
UIActivityIndicator.appearance().hidden = true
UIActivityIndicatorView.appearance().hidesWhenStopped = true
不知道这会为应用程序的其余部分取消分配指示器,所以当我在登录逻辑中调用以下内容时:
activityIND.hidden = false
activityIND.startAnimating()
我正在向不再可用的实例发送消息,导致崩溃。所以我所做的就是在 viewDidLoad()
中调整我的代码
至:
activityIND.hidden = true
activityIND.hidesWhenStopped = true
使用我创建的特定插座的名称而不是通用名称 UIActivityIndicatorView
所有 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
}
};
}
}
}
当我在我的应用程序中执行特定操作时,我一直收到 EXC_BAD_ACCESS error/crash。确定这是一个内存管理问题,我启用了 NSZombies 来帮助我破译这个问题。崩溃后,我的控制台给了我以下消息:
这是我的堆栈跟踪:
以及突出显示我的应用委托行的新错误:
现在调试器指的是 UIActivityIndicatorRelease,我的堆栈跟踪中唯一突出显示的代码行是我的委托中的第一行,我的代码有问题吗Activity 指标 UI 元素?这是我的登录操作中的逻辑(每次都会强制崩溃):
@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)"
}
}
}
}
里面有没有错误?
所有绝对、肯定地操作 UI 对象的代码都必须从主线程完成。 (因此,正如@JAL 在他的评论中所说,它应该在对 dispatch_async(dispatch_get_main_queue())
的调用中。
这不仅包括 self.activityIND.stopAnimating()
行,还包括设置标签文本的代码(任何像 UIView 一样操作 UIKit 对象的代码)。
您的 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)"
}
}
}
事实证明,在我的 viewDidLoad()
中,我有以下代码试图隐藏负载上的指示器:
UIActivityIndicator.appearance().hidden = true
UIActivityIndicatorView.appearance().hidesWhenStopped = true
不知道这会为应用程序的其余部分取消分配指示器,所以当我在登录逻辑中调用以下内容时:
activityIND.hidden = false
activityIND.startAnimating()
我正在向不再可用的实例发送消息,导致崩溃。所以我所做的就是在 viewDidLoad()
中调整我的代码
至:
activityIND.hidden = true
activityIND.hidesWhenStopped = true
使用我创建的特定插座的名称而不是通用名称 UIActivityIndicatorView
所有 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 } }; } } }