注册观察者时 viewDidLoad() 崩溃

Crash in viewDidLoad() when registering observers

我在 viewDidLoad 发生了一次崩溃。我无法弄清楚为什么会这样。下面是崩溃跟踪和所有代码。

class WriteTestimonialViewController: UIViewController, UITextViewDelegate {
    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.addPurpleBackground()

        title = "Write Testimonial"

        testimonialTextView.clearTextView(text: "Type testimonial")

        // Setup keyboard event
        NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillShow(notification:)), name: UIResponder.keyboardWillShowNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillHide(notification:)), name: UIResponder.keyboardWillHideNotification, object: nil)
        // Dismiss keyboard
        self.hideKeyboardWhenTappedAround()
    }

    // Setup keyboard event
    @objc func keyboardWillShow(notification:NSNotification){
        var userInfo = notification.userInfo!
        var keyboardFrame:CGRect = (userInfo[UIResponder.keyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue
        keyboardFrame = self.view.convert(keyboardFrame, from: nil)

        var contentInset:UIEdgeInsets = self.scrollView.contentInset
        contentInset.bottom = keyboardFrame.size.height
        scrollView.contentInset = contentInset
    }

    @objc func keyboardWillHide(notification:NSNotification){

        let contentInset:UIEdgeInsets = UIEdgeInsets.zero
        scrollView.contentInset = contentInset
    }

 }

extension UIViewController {

    // Dismiss keyboard on touch
    func hideKeyboardWhenTappedAround() {
        let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(UIViewController.dismissKeyboard))
        tap.cancelsTouchesInView = false
        view.addGestureRecognizer(tap)
    }

    @objc func dismissKeyboard() {
        view.endEditing(true)
    }
}

func addPurpleBackground() {
    let imageViewBackground = UIImageView()
    imageViewBackground.image = UIImage(named: "bgimage")

    imageViewBackground.contentMode = .scaleAspectFill
    imageViewBackground.clipsToBounds = true
    imageViewBackground.translatesAutoresizingMaskIntoConstraints = false

    self.insertSubview(imageViewBackground, at: 0)

    self.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "|[imageViewBackground]|",
                                                       options: [],
                                                       metrics: nil,
                                                       views: ["imageViewBackground": imageViewBackground]))
    self.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[imageViewBackground]|",
                                                       options: [],
                                                       metrics: nil,
                                                       views: ["imageViewBackground": imageViewBackground]))
}

我认为在viewWillAppear/viewDidAppear中注册通知会更好,只有当视图实际显示时您才会对通知感兴趣。如果将其保留在 viewDidLoad 中,有时会发生视图已加载但未立即出现在屏幕上的情况。

还有From iOS 9 you don't need anymore to manually remove observer.

In OS X 10.11 and iOS 9.0 NSNotificationCenter and NSDistributedNotificationCenter will no longer send notifications to registered observers that may be deallocated