Сообщение NotificationCenter о Swift 3

Я изучаю Swift 3, и я пытаюсь использовать NSNotificationCenter. Вот мой код:

func savePost(){
    let postData = NSKeyedArchiver.archivedData(withRootObject: _loadedpost)
    UserDefaults.standard().object(forKey: KEY_POST)
}
func loadPost(){
    if let postData = UserDefaults.standard().object(forKey: KEY_POST) as? NSData{
        if let postArray = NSKeyedUnarchiver.unarchiveObject(with: postData as Data) as? [Post]{
                _loadedpost = postArray
        }
    }
    //codeerror
    NotificationCenter.default().post(NSNotification(name: "loadedPost" as NSNotification.Name, object: nil) as Notification)
}

и это наблюдатель:

override func viewDidLoad() {
    super.viewDidLoad()
//codeerorr
    NotificationCenter.default().addObserver(self, selector: Selector(("onPostLoaded")), name: "loadedPost", object: nil)
}

func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

Он всегда дает мне ошибку "сигнал SIGBRT". Когда я пытаюсь изменить имя в наблюдателе, это не ошибка, но, очевидно, ничего не показывало. Как это исправить?

Ответ 1

Swift 3 и 4

Swift 3, а теперь Swift 4 заменили многие "строчно типизированные" API с struct "типами обертки", как в случае с NotificationCenter. Уведомления теперь идентифицируются с помощью struct Notfication.Name, а не String. Для получения дополнительной информации см. Теперь устаревшее Переход к руководству Swift 3

Swift 2.2:

// Define identifier
let notificationIdentifier: String = "NotificationIdentifier"

// Register to receive notification
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(YourClassName.methodOfReceivedNotification(_:)), name: notificationIdentifier, object: nil)

// Post a notification
NSNotificationCenter.defaultCenter().postNotificationName(notificationIdentifier, object: nil)

Использование Swift 3 и 4:

// Define identifier
let notificationName = Notification.Name("NotificationIdentifier")

// Register to receive notification
NotificationCenter.default.addObserver(self, selector: #selector(YourClassName.methodOfReceivedNotification), name: notificationName, object: nil)

// Post notification
NotificationCenter.default.post(name: notificationName, object: nil)

// Stop listening notification
NotificationCenter.default.removeObserver(self, name: notificationName, object: nil)

Все типы системных уведомлений теперь определяются как статические константы на Notification.Name; т.е. .UIApplicationDidFinishLaunching, .UITextFieldTextDidChange и т.д.

Вы можете расширить Notification.Name своими собственными уведомлениями, чтобы оставаться в соответствии с системными уведомлениями:

// Definition:
extension Notification.Name {
    static let yourCustomNotificationName = Notification.Name("yourCustomNotificationName")
}

// Usage:
NotificationCenter.default.post(name: .yourCustomNotificationName, object: nil)

Ответ 2

Для всех, кто борется С#selector в SWIFT 3, здесь приведен полный код:

// WE NEED A RECEIVING CLASS
    class MyReceivingClass {

    // ----------------------------------------------------------------------------------------
    // INIT -> GOOD PLACE FOR REGISTERING
    // ----------------------------------------------------------------------------------------
    init() {
        // WE REGISTER FOR SYSTEM NOTIFICATION (APP WILL RESIGN ACTIVE)

        // Register without parameter
        NotificationCenter.default.addObserver(self, selector: #selector(MyReceivingClass.handleNotification), name: .UIApplicationWillResignActive, object: nil)

        // Register WITH parameter
        NotificationCenter.default.addObserver(self, selector: #selector(MyReceivingClass.handle(withNotification:)), name: .UIApplicationWillResignActive, object: nil)
    }

    // ----------------------------------------------------------------------------------------
    // DE-INIT -> LAST OPTION FOR RE-REGISTERING
    // ----------------------------------------------------------------------------------------
    deinit {
        NotificationCenter.default.removeObserver(self)
    }

    // Either "MyReceivingClass" must be subclassed of NSObject OR selector-methods MUST BE signed with '@objc'

    // ----------------------------------------------------------------------------------------
    // HANDLE NOTIFICATION WITHOUT PARAMETER
    // ----------------------------------------------------------------------------------------
    @objc func handleNotification() {
        print("RECEIVED ANY NOTIFICATION")
    }

    // ----------------------------------------------------------------------------------------
    // HANDLE NOTIFICATION WITH PARAMETER
    // ----------------------------------------------------------------------------------------
    @objc func handle(withNotification notification : NSNotification) {
        print("RECEIVED SPECIFIC NOTIFICATION: \(notification)")
    }
}

В этом примере мы пытаемся получить POST из AppDelegate (поэтому в AppDelegate реализовать это):

// ----------------------------------------------------------------------------------------
// WHEN APP IS GOING TO BE INACTIVE
// ----------------------------------------------------------------------------------------
func applicationWillResignActive(_ application: UIApplication) {

    print("POSTING")

    // Define identifiyer
    let notificationName = Notification.Name.UIApplicationWillResignActive

    // Post notification
    NotificationCenter.default.post(name: notificationName, object: nil)
}

Ответ 3

Уведомления снова изменились (октябрь 2016 года).

//Зарегистрируйтесь для получения уведомлений

NotificationCenter.default.addObserver(self, selector: #selector(yourClass.yourMethod), name: NSNotification.Name(rawValue: "yourNotificatioName"), object: nil)

//Почтовое уведомление

NotificationCenter.default.post(name: NSNotification.Name(rawValue: "yourNotificationName"), object: nil)

Ответ 4

Я думаю, что он снова изменился.

Для публикации этой работы в Xcode 8.2.

NotificationCenter.default.post(Notification(name:.UIApplicationWillResignActive)