扩展 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)

我注意到便利初始化器也存在同样的问题。 它实际上是同时出现两个错误。

  1. Swift 分配一个 UIAlertController 实例。
  2. Swift 使用 Swift.
  3. 创建的实例调用您的便利 init
  4. 那里调用了UIKit的convenience init,其实就是Objective-C工厂方法+(id) alertControllerWithTitle:message:preferredStyle:.
  5. 那里 UIKit 分配了它自己的 UIAlertController 实例。 (错误 #1)
  6. UIKit 设置自己的实例。
  7. UIKit 取消分配您的 Swift 实例。
  8. UIAlertControllerdeinit(dealloc)访问导致日志消息的 view 属性。 (错误 #2)
  9. 控制返回到您自己的便利初始化,其中 self 默默地从 Swift 的 UIAlertController 实例更改为来自 UIKit 的实例。
  10. 你现在所做的一切都发生在 UIKit 创建的实例上,这很好。

所以第一个错误是 Swift 创建了一个临时的 UIAlertController,它在没有被使用的情况下被销毁了。

第二个错误是 UIViewController 在取消初始化期间访问了 view 属性,这是不应该的。


关于您的问题:
这两个错误应该都不是问题,所以我们现在可以简单地忽略警告。我也这样做了,目前还没有任何问题 - 只是日志中的那个警告。