In the process of resolving a legacy code, I wanted to encapsulate UIAlertView a bit to separate the specific AlertView code from the huge ViewController, and I did this:

import UIKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window : UIWindow? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { window = UIWindow() window! .rootViewController = UIViewController() window! .rootViewController! .view.backgroundColor = .blue window! .makeKeyAndVisible() let a = AlertView() a.show() return true } } class AlertView : UIViewController,UIAlertViewDelegate{ var done : ((_ buttonIndex: Int)->Void)? func show(){ var createAccountErrorAlert: UIAlertView = UIAlertView() createAccountErrorAlert.delegate = self createAccountErrorAlert.title = "Oops" createAccountErrorAlert.message = "Could not create account!" createAccountErrorAlert.addButton(withTitle: "Dismiss") createAccountErrorAlert.addButton(withTitle: "Retry") createAccountErrorAlert.show() } func alertView(_ alertView: UIAlertView, clickedButtonAt buttonIndex: Int){ print("Why delegate of alert view does not work?" )}}Copy the code

Surprisingly, click on the button, alertView: clickedButtonAt: just don’t perform. And then the problem is solved pretty quickly, because the AlertView instance is local, the instance is freed after the code executes, and the delegate is gone.

The solution is simple:

let a = AlertView()Copy the code

to

    var a : AlertView
    ...
    a = AlertView()Copy the code

Can.