Проблема Центра уведомлений на 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". Когда я пытаюсь изменить имя в обозревателе, это не ошибка, но, очевидно, он ничего не показывает. Как это исправить?
4 ответа
Свифт 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)
Использование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)
Для всех, кто борется с #selector в Swift 3 или Swift 4, вот полный пример кода:
// 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)")
}
}
В этом примере мы пытаемся получить 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)
}
Уведомления снова изменились (октябрь 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)
Я думаю, что это снова изменилось.
Для публикации это работает в Xcode 8.2.
NotificationCenter.default.post(Notification(name:.UIApplicationWillResignActive)