ios Swift 3 上的通知中心问题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/38204703/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 09:37:42  来源:igfitidea点击:

NotificationCenter issue on Swift 3

iosswift3notificationcenter

提问by RoccoBerry

I'm learning Swift 3 and I'm trying to using NSNotificationCenter. Here is my code:

我正在学习 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)
}

and this is the observer:

这是观察者:

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
}

It always gives me the error "signal SIGBRT". When I try to change the name in the observer, it's not an error, but obviously it didn't show anything. How do I fix this?

它总是给我错误“信号 SIGBRT”。当我尝试在观察者中更改名称时,这不是错误,但显然它没有显示任何内容。我该如何解决?

回答by Jeffrey Fulton

Swift 3 & 4

斯威夫特 3 & 4

Swift 3, and now Swift 4, have replaced many "stringly-typed" APIs with struct"wrapper types", as is the case with NotificationCenter. Notifications are now identified by a struct Notfication.Namerather than by String. For more details see the now legacy Migrating to Swift 3 guide

Swift 3 和现在的 Swift 4 已经用struct“包装器类型”替换了许多“字符串类型”的 API ,就像 NotificationCenter 的情况一样。通知现在由 标识struct Notfication.Name而不是由标识String。有关更多详细信息,请参阅现在遗留的迁移到 Swift 3 指南

Swift 2.2usage:

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 & 4usage:

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)

All of the system notification types are now defined as static constants on Notification.Name; i.e. .UIApplicationDidFinishLaunching, .UITextFieldTextDidChange, etc.

所有系统通知类型现在都定义为静态常量Notification.Name;即.UIApplicationDidFinishLaunching.UITextFieldTextDidChange等等。

You can extend Notification.Namewith your own custom notifications in order to stay consistent with the system notifications:

您可以Notification.Name使用自己的自定义通知进行扩展,以与系统通知保持一致:

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

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

Swift 4.2usage:

Swift 4.2用法:

Same as Swift 4, except now system notifications names are part of UIApplication. So in order to stay consistent with the system notifications you can extend UIApplicationwith your own custom notifications instead of Notification.Name :

与 Swift 4 相同,除了现在系统通知名称是 UIApplication 的一部分。因此,为了与系统通知保持一致,您可以UIApplication使用自己的自定义通知而不是 Notification.Name进行扩展:

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

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

回答by David DelMonte

Notifications appear to have changed again (October 2016).

通知似乎再次发生了变化(2016 年 10 月)。

// Register to receive notification

//注册接收通知

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

// Post notification

// 发布通知

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

回答by LukeSideWalker

For all struggling around with the #selector in Swift 3 or Swift 4, here a full code example:

对于所有在 Swift 3 或 Swift 4 中为 #selector 苦苦挣扎的人,这里有一个完整的代码示例:

// WE NEED A CLASS THAT SHOULD RECEIVE NOTIFICATIONS
    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 a subclass 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)")
    }
}

In this example we try to get POSTs from AppDelegate (so in AppDelegate implement this):

在这个例子中,我们尝试从 AppDelegate 获取 POSTs(所以在 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)
}

回答by Muge Cevik

I think it has changed again.

我想它又变了。

For posting this works in Xcode 8.2.

为了在 Xcode 8.2 中发布此作品。

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