When I define a UIAlertController
convenience initializer:
extension UIAlertController {
convenience init(message: String?) {
self.init(title: nil, message: message, preferredStyle: .Alert)
self.addAction(UIAlertAction(title: "OK", style: .Cancel, handler: nil))
}
}
and use it in a button action in my subclass of UIViewController
:
func buttonAction(button: UIButton) {
let alert = UIAlertController(dictionary: nil, error: nil, handler: nil)
presentViewController(alert, animated: true, completion: nil)
}
and click that button on the Simulator, I get a warning:
Attempting to load the view of a view controller while it is deallocating is not allowed and may result in undefined behavior (UIAlertController)
However, I don't get a warning if instead of a convenience initializer, I use a global function:
func UIAlertControllerWithDictionary(message: String?) -> UIAlertController {
let alert = UIAlertController(title: nil, message: message, preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "OK", style: .Cancel, handler: nil))
return alert
}
I've reported this to Apple as an iOS SDK bug.
Until it's fixed, is it OK to ignore the warning and use the convenience initializer?
I noticed the same issue with convenience initializers. It's actually two bugs at once.
UIAlertController
instance.+(id) alertControllerWithTitle:message:preferredStyle:
.UIAlertController
instance. (Bug #1)
UIAlertController
's deinit
(dealloc) accesses the view
property which leads to the log message. (Bug #2)
self
silently changed from Swift's UIAlertController
instance to the one from UIKit.So the first bug is that Swift creates a temporary UIAlertController
which is destroyed without ever being used.
The second bug is that UIViewController
accesses the view
property during deinitialization which it shouldn't.
Regarding your question:
Both bugs shouldn't be problematic so we can simply ignore the warning for now. I do that too and there weren't any problems yet - just that warning in the log.
I also faced the same issue
Attempting to load the view of a view controller while it is deallocating is not allowed and may result in undefined behavior (UIAlertController)
So I moved to the alternate way for this.
import UIKit
import Foundation
//the show alert function for failure
func showAlertforNetworkFailure(alerttitle :String, alertmessage: String,ButtonTitle: String, viewController: UIViewController)
{
let alertController = UIAlertController(title: alerttitle, message: alertmessage, preferredStyle: .Alert)
let okButtonOnAlertAction = UIAlertAction(title: ButtonTitle, style: .Default)
{ (action) -> Void in
//what happens when "ok" is pressed
}
alertController.addAction(okButtonOnAlertAction)
alertController.show()
}
// function for show alert in Main View Controller
extension UIAlertController {
func show() {
present(true, completion: nil)
}
func present(animated: Bool, completion: (() -> Void)?) {
if let rootVC = UIApplication.sharedApplication().keyWindow?.rootViewController {
presentFromController(rootVC, animated: animated, completion: completion)
}
}
private func presentFromController(controller: UIViewController, animated: Bool, completion: (() -> Void)?) {
if let navVC = controller as? UINavigationController,
let visibleVC = navVC.visibleViewController {
presentFromController(visibleVC, animated: animated, completion: completion)
} else {
controller.presentViewController(self, animated: animated, completion: completion);
}
}
}
call this method in your ViewController as
showAlertforNetworkFailure("Server Error!!!", alertmessage: "Server does not responding,please Try in later.", ButtonTitle: "Okay", viewController: self)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With