web-dev-qa-db-ja.com

Swift 3でのNotificationCenterの問題

私は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"を与えます。オブザーバで名前を変更しようとしてもエラーにはなりませんが、明らかに何も表示されませんでした。これをどのように修正しますか?

91
RoccoBerry

スイフト3&4

NotificationCenterの場合と同様に、Swift 3とSwift 4は、多くの "文字列型" APIをstruct "ラッパー型"に置き換えました。通知はStringではなくstruct Notfication.Nameによって識別されるようになりました。詳細については、現在のレガシー 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の一部になった点が異なります。そのため、システム通知との一貫性を保つために、Notification.Nameの代わりに独自のカスタム通知を使用してUIApplicationを拡張できます。

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

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

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)
}
18
LukeSideWalker

通知が再び変更されたようです(2016年10月)。

//通知を受け取るために登録

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)
15
David DelMonte

また変わったと思います。

投稿するために、これはXcode 8.2で動作します。

NotificationCenter.default.post(Notification(name:.UIApplicationWillResignActive)
5
Muge Cevik