Swift 3上的NotificationCenter问题

Roc*_*rry 91 ios notificationcenter swift3

我正在学习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)
}
Run Code Online (Sandbox Code Playgroud)

这是观察者:

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
}
Run Code Online (Sandbox Code Playgroud)

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

Jef*_*ton 325

斯威夫特3和4

Swift 3,现在是Swift 4,已经用struct"包装类型" 替换了许多"字符串类型"的API ,就像NotificationCenter一样.现在通过a struct Notfication.Name而不是by来识别通知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)
Run Code Online (Sandbox Code Playgroud)

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)
Run Code Online (Sandbox Code Playgroud)

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

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

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

// Usage:
NotificationCenter.default.post(name: .yourCustomNotificationName, object: nil)
Run Code Online (Sandbox Code Playgroud)

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)
Run Code Online (Sandbox Code Playgroud)


Luk*_*ker 18

对于所有在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)")
    }
}
Run Code Online (Sandbox Code Playgroud)

在这个例子中,我们尝试从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)
}
Run Code Online (Sandbox Code Playgroud)


Dav*_*nte 17

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

//注册接收通知

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

//发布通知

NotificationCenter.default.post(name: NSNotification.Name(rawValue: "yourNotificationName"), object: nil)
Run Code Online (Sandbox Code Playgroud)


小智 5

我认为它已经改变了.

发布此内容适用于Xcode 8.2.

NotificationCenter.default.post(Notification(name:.UIApplicationWillResignActive)
Run Code Online (Sandbox Code Playgroud)