扩展 UIAlertController 便利初始化警告
extension UIAlertController convenience init warning
当我定义一个 UIAlertController
便利初始值设定项时:
extension UIAlertController {
convenience init(message: String?) {
self.init(title: nil, message: message, preferredStyle: .Alert)
self.addAction(UIAlertAction(title: "OK", style: .Cancel, handler: nil))
}
}
并在我 UIViewController
的子类中的按钮操作中使用它:
func buttonAction(button: UIButton) {
let alert = UIAlertController(dictionary: nil, error: nil, handler: nil)
presentViewController(alert, animated: true, completion: nil)
}
然后单击模拟器上的那个按钮,我收到警告:
Attempting to load the view of a view controller while it is deallocating is not allowed and may result in undefined behavior (UIAlertController)
但是,如果我使用全局函数而不是便利初始化程序,我不会收到警告:
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
}
我已将此作为 iOS SDK 错误报告给 Apple。
在修复之前,可以忽略警告并使用便利初始化程序吗?
我也遇到了同样的问题
Attempting to load the view of a view controller while it is deallocating is not allowed and may result in undefined behavior (UIAlertController)
所以我换了个方法。
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);
}
}
}
在您的 ViewController 中调用此方法
showAlertforNetworkFailure("Server Error!!!", alertmessage: "Server does not responding,please Try in later.", ButtonTitle: "Okay", viewController: self)
我注意到便利初始化器也存在同样的问题。
它实际上是同时出现两个错误。
- Swift 分配一个
UIAlertController
实例。
- Swift 使用 Swift.
创建的实例调用您的便利 init
- 那里调用了UIKit的convenience init,其实就是Objective-C工厂方法
+(id) alertControllerWithTitle:message:preferredStyle:
.
- 那里 UIKit 分配了它自己的
UIAlertController
实例。 (错误 #1)
- UIKit 设置自己的实例。
- UIKit 取消分配您的 Swift 实例。
UIAlertController
的 deinit
(dealloc)访问导致日志消息的 view
属性。 (错误 #2)
- 控制返回到您自己的便利初始化,其中
self
默默地从 Swift 的 UIAlertController
实例更改为来自 UIKit 的实例。
- 你现在所做的一切都发生在 UIKit 创建的实例上,这很好。
所以第一个错误是 Swift 创建了一个临时的 UIAlertController
,它在没有被使用的情况下被销毁了。
第二个错误是 UIViewController
在取消初始化期间访问了 view
属性,这是不应该的。
关于您的问题:
这两个错误应该都不是问题,所以我们现在可以简单地忽略警告。我也这样做了,目前还没有任何问题 - 只是日志中的那个警告。
当我定义一个 UIAlertController
便利初始值设定项时:
extension UIAlertController {
convenience init(message: String?) {
self.init(title: nil, message: message, preferredStyle: .Alert)
self.addAction(UIAlertAction(title: "OK", style: .Cancel, handler: nil))
}
}
并在我 UIViewController
的子类中的按钮操作中使用它:
func buttonAction(button: UIButton) {
let alert = UIAlertController(dictionary: nil, error: nil, handler: nil)
presentViewController(alert, animated: true, completion: nil)
}
然后单击模拟器上的那个按钮,我收到警告:
Attempting to load the view of a view controller while it is deallocating is not allowed and may result in undefined behavior (UIAlertController)
但是,如果我使用全局函数而不是便利初始化程序,我不会收到警告:
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
}
我已将此作为 iOS SDK 错误报告给 Apple。
在修复之前,可以忽略警告并使用便利初始化程序吗?
我也遇到了同样的问题
Attempting to load the view of a view controller while it is deallocating is not allowed and may result in undefined behavior (UIAlertController)
所以我换了个方法。
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);
}
}
}
在您的 ViewController 中调用此方法
showAlertforNetworkFailure("Server Error!!!", alertmessage: "Server does not responding,please Try in later.", ButtonTitle: "Okay", viewController: self)
我注意到便利初始化器也存在同样的问题。 它实际上是同时出现两个错误。
- Swift 分配一个
UIAlertController
实例。 - Swift 使用 Swift. 创建的实例调用您的便利 init
- 那里调用了UIKit的convenience init,其实就是Objective-C工厂方法
+(id) alertControllerWithTitle:message:preferredStyle:
. - 那里 UIKit 分配了它自己的
UIAlertController
实例。 (错误 #1) - UIKit 设置自己的实例。
- UIKit 取消分配您的 Swift 实例。
UIAlertController
的deinit
(dealloc)访问导致日志消息的view
属性。 (错误 #2)- 控制返回到您自己的便利初始化,其中
self
默默地从 Swift 的UIAlertController
实例更改为来自 UIKit 的实例。 - 你现在所做的一切都发生在 UIKit 创建的实例上,这很好。
所以第一个错误是 Swift 创建了一个临时的 UIAlertController
,它在没有被使用的情况下被销毁了。
第二个错误是 UIViewController
在取消初始化期间访问了 view
属性,这是不应该的。
关于您的问题:
这两个错误应该都不是问题,所以我们现在可以简单地忽略警告。我也这样做了,目前还没有任何问题 - 只是日志中的那个警告。