Swift 3 上的 NotificationCenter 问题
NotificationCenter issue on 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
}
它总是给我错误 "signal SIGBRT"。当我尝试在观察者中更改名称时,这不是错误,但显然它没有显示任何内容。我该如何解决这个问题?
Swift 3 & 4
Swift 3,现在 Swift 4,已经将许多 "stringly-typed" API 替换为 struct
"wrapper types",NotificationCenter 也是如此。通知现在由 struct Notfication.Name
而不是 String
标识。有关更多详细信息,请参阅现在的遗产 Migrating to Swift 3 guide
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)
Swift 4.2 用法:
与 Swift 4 相同,除了现在系统通知名称是 UIApplication 的一部分。因此,为了与系统通知保持一致,您可以使用自己的自定义通知来扩展 UIApplication
而不是 Notification.Name :
// Definition:
UIApplication {
public static let yourCustomNotificationName = Notification.Name("yourCustomNotificationName")
}
// Usage:
NotificationCenter.default.post(name: UIApplication.yourCustomNotificationName, object: nil)
通知似乎又发生了变化(2016 年 10 月)。
// 注册接收通知
NotificationCenter.default.addObserver(self, selector: #selector(yourClass.yourMethod), name: NSNotification.Name(rawValue: "yourNotificatioName"), object: nil)
// Post通知
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "yourNotificationName"), object: nil)
对于所有在 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)")
}
}
在这个例子中,我们尝试从 AppDelegate 获取 POST(所以在 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)
}
我觉得又变了
为了在 Xcode 8.2.
中发布此作品
NotificationCenter.default.post(Notification(name:.UIApplicationWillResignActive)
我正在学习 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
}
它总是给我错误 "signal SIGBRT"。当我尝试在观察者中更改名称时,这不是错误,但显然它没有显示任何内容。我该如何解决这个问题?
Swift 3 & 4
Swift 3,现在 Swift 4,已经将许多 "stringly-typed" API 替换为 struct
"wrapper types",NotificationCenter 也是如此。通知现在由 struct Notfication.Name
而不是 String
标识。有关更多详细信息,请参阅现在的遗产 Migrating to Swift 3 guide
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)
Swift 4.2 用法:
与 Swift 4 相同,除了现在系统通知名称是 UIApplication 的一部分。因此,为了与系统通知保持一致,您可以使用自己的自定义通知来扩展 UIApplication
而不是 Notification.Name :
// Definition:
UIApplication {
public static let yourCustomNotificationName = Notification.Name("yourCustomNotificationName")
}
// Usage:
NotificationCenter.default.post(name: UIApplication.yourCustomNotificationName, object: nil)
通知似乎又发生了变化(2016 年 10 月)。
// 注册接收通知
NotificationCenter.default.addObserver(self, selector: #selector(yourClass.yourMethod), name: NSNotification.Name(rawValue: "yourNotificatioName"), object: nil)
// Post通知
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "yourNotificationName"), object: nil)
对于所有在 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)")
}
}
在这个例子中,我们尝试从 AppDelegate 获取 POST(所以在 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)
}
我觉得又变了
为了在 Xcode 8.2.
中发布此作品NotificationCenter.default.post(Notification(name:.UIApplicationWillResignActive)