如果视图被关闭,单击 UIAlertView 会使应用程序崩溃
如果发生错误,则会显示 UIAlertView
。但与此同时,调用 UIAlertView
的视图已被驳回(因此被释放)。如果用户单击“确定”,应用程序就会崩溃,因为会向已发布的实例发送消息。这将导致您的应用程序崩溃:
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"test" message:@"test" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alertView show];
[alertView release];
alertView = nil;
[self.navigationController popViewControllerAnimated:YES];
我认为 UIAlertView 是一个独立的单元。但似乎并非如此。有没有办法避免应用程序崩溃(除了不关闭视图)?
A UIAlertView
is displayed if an error occurs. But in the meantime the view on which the UIAlertView
were called has been dismissed (and therefore released). If the user clicks on OK the app crashes because a message to a released instance is sent. This will cause your app crashing:
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"test" message:@"test" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alertView show];
[alertView release];
alertView = nil;
[self.navigationController popViewControllerAnimated:YES];
I thought the UIAlertView
is an independent unit. But it seems it isn't. Is there a way how I could avoid the app crashing (except not dismissing the view)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
当
UIAlertView
被解除时,会调用委托,因此在您的情况下:不会保留委托,就像添加到数组中的对象或子视图一样。因此,在您的情况下,当您调用:
self
很可能被释放,并且当用户解除警报时,self
被调用,但已被释放,因此它不再存在了。检查这一点的一个简单方法是在
self
的dealloc
NSLog(@"I'm gone"); > 方法,如果它运行了,那么你就知道你的self
已经不存在了,发送给它的任何消息都会导致崩溃。The delegate is called when the
UIAlertView
is dismissed, so in your case:Delegates are not retained, like an object added to an array, or a subview would be. So in your case, when you call:
self
is most likely being released, and when the the user dismisses the alert,self
is called, but has been dealloc'd so it no longer exists.An easy way to check this is to put a logger statement, like
NSLog(@"I'm gone");
inself
'sdealloc
method, if it's ran, then you know yourself
isn't around anymore, and any messages sent to it will cause a crash.将 UIAlertView 设为视图控制器的保留属性,以便您可以在释放中引用它,然后在释放视图控制器时将警报视图的委托设置为 nil。
一旦保留的警报视图被解除并释放,请确保正确释放它。
例如:
这里的缺点是,当用户关闭警报视图时,您将无法处理警报视图的回调。但是,由于您的控制器已经消失/发布,因此您可能不需要这样做。如果这样做,您必须将警报视图的委托设置为将持续存在的内容。
Make the UIAlertView a retained property of your view controller so that you can refer to it in your dealloc, then set the alert view's delegate to nil when the view controller is deallocated.
Be sure to properly release the retained alert view once it's been dismissed and on dealloc.
For instance:
The downside here is that you will not be able to handle the alert view's callback when the user dismisses it. However, since your controller is already gone/released, presumably you don't need to. If you do, you have to set the alert view's delegate to something that will persist.
如果 UIAlertView 对象可以从应用程序中的任何位置使用,而不仅仅是在当前视图上,那么请将其保留在应用程序中任何地方都可用的东西中,或者是整个可能的视图堆栈下的某个持久根视图控制器,或者是应用程序委托。
添加:
此顶级对象还可以保留警报视图的委托,直到需要它为止(警报视图关闭后)。
If the UIAlertView object is to be usable from anywhere in the app, not just on the current view, then retain it inside something that is available from anywhere in the app, either some persistant root view controller under the entire possible view stack, or the app delegate.
Added:
This top level object can also retain the alert view's delegate until after it's done being needed (after alert view dismissal).
(人们可能想知道我回答这个问题已经晚了好几年,但这可能对其他人有帮助)
我想你的问题在于弹出视图控制器,你正在显示警报视图,同时尝试导航用户回到视图。我建议您在这里遵循分层方法,即:
首先将警报视图声明为全局对象,即
现在在需要的地方编写警报视图显示代码,例如:
最后尝试导航当按下“确定”按钮时,用户转到所需的视图,即您需要使用alertView
didDismissWithButtonIndex
方法,即请注意,如果您有带有多个按钮的警报视图,您还需要检查用于区分操作的按钮索引,即检查使用
这肯定会避免应用程序崩溃,谢谢:)
(People might wonder I am late by years in answering this question,but it might help someone else)
I guess your problem lies some where in popping the view controller,you are displaying the alert view and at the same time trying to navigate the user back to a view.I would recommend you to follow a hierarchal approach here i.e.:
First of all declare your alert view as a global object,i.e.
Now write your alert view display code where ever desired,say for instance:
Finally try to navigate the user to the desired view when the "Ok" button is pressed,i.e. you need to make use of alertView
didDismissWithButtonIndex
method,i.e.Please note that if you have alert view with multiple buttons,you also need to check for button index for distinguishing actions,i.e. check using
This will definitely avoid application crash,thanks :)
对我来说更简单的方法是将所有警报视图保存在一个数组中,当父视图被释放时,枚举alertViews数组并将委托分配为nil。这将确保触摸事件被忽略并且应用程序将正常运行。
Easier way that worked for me is to hold all the alert views in a Array and when the parent view is deallocated enumerate alertViews array and assign the delegate to nil. This will ensure that the touch event is ignored and app will function.
确保您正在实现
UIAlertViewDelegate
协议。如果您不关心警报何时解除,只需将委托初始化为
nil
。Make sure you are implementing the
UIAlertViewDelegate
protocol.If you don't care about when the alert is dismissed just init with delegate as
nil
.