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”。当我试图更改观察者中的名称时,这不是一个错误,但显然它没有显示任何东西。我该怎么补救?

117934 次浏览

Swift 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.Name rather than by String. For more details see the now legacy Migrating to Swift 3 guide

Swift 2.2 usage:

// 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 usage:

// 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.

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

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


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

Swift 4.2 usage:

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 UIApplication with your own custom notifications instead of Notification.Name :

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


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

Notifications appear to have changed again (October 2016).

// 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)

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

// 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):

// ---------------------------------------------
// 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)
}

I think it has changed again.

For posting this works in Xcode 8.2.

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