Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/107.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Swift iOS中注销NSNotification_Ios_Swift_Nsnotificationcenter - Fatal编程技术网

如何在Swift iOS中注销NSNotification

如何在Swift iOS中注销NSNotification,ios,swift,nsnotificationcenter,Ios,Swift,Nsnotificationcenter,我有两个控制器 class CtrlA: UIViewController { override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) NotificationCenter.default.addObserver(CtrlB.self, selector: #selector(CtrlB.badge(notification:)), name: NSN

我有两个控制器

class CtrlA: UIViewController {
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        NotificationCenter.default.addObserver(CtrlB.self, selector: #selector(CtrlB.badge(notification:)), name: NSNotification.Name(rawValue: "badge"), object: nil)
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)

        NotificationCenter.default.removeObserver(CtrlB.self, name: NSNotification.Name(rawValue: "badge"), object: nil)
    }
}

class CtrlB: UIViewController {
    static func badge (notification: NSNotification) {
        // blah blah
    }
}
取消注册上述通知侦听器的正确方法是什么? 我不确定这是否正确:

NotificationCenter.default.removeObserver(CtrlB.self,名称:NSNotification.name(rawValue:“badge”),对象:nil)


我想我也不能使用
self
,因为它是在
CtrlB.self

上注册的。我不知道你为什么要用类而不是实例注册/注销通知。”self'-不会给您一个CtrlB类的实例,实际上它会返回一个类本身。 相反,您应该使用如下内容:

class CtrlA {

    let ctrlBInstance = CtrlB()

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        NotificationCenter.default.addObserver(ctrlBInstance, selector: #selector(CtrlB.badge(notification:)), name: NSNotification.Name(rawValue: "badge"), object: nil)
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)

        NotificationCenter.default.removeObserver(ctrlBInstance, name: NSNotification.Name(rawValue: "badge"), object: nil)
    }
}
在这种情况下,您的ClassB应该如下所示:

class CtrlB {
   func badge (notification: NSNotification) {
        // blah blah
    }
}

我不知道您为什么要用类而不是实例注册/注销通知。”self'-不会给您一个CtrlB类的实例,实际上它会返回一个类本身。 相反,您应该使用如下内容:

class CtrlA {

    let ctrlBInstance = CtrlB()

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        NotificationCenter.default.addObserver(ctrlBInstance, selector: #selector(CtrlB.badge(notification:)), name: NSNotification.Name(rawValue: "badge"), object: nil)
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)

        NotificationCenter.default.removeObserver(ctrlBInstance, name: NSNotification.Name(rawValue: "badge"), object: nil)
    }
}
在这种情况下,您的ClassB应该如下所示:

class CtrlB {
   func badge (notification: NSNotification) {
        // blah blah
    }
}

您需要获取观察器的实例,但尚未声明该实例

例如,您需要设置类变量secondA

class CtrlA: UIViewController {

var secondController: CtrlB?


override func viewDidLoad()
{
super.viewDidLoad()

    if let unwrappedController = storyboard.instantiateViewController(withIdentifier: "someViewController") as? CtrlB
    {
    secondController = unwrappedController        
    }

}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    if let secondController = secondController
    {
    NotificationCenter.default.addObserver(CtrlB.self, selector: #selector(CtrlB.badge(notification:)), name: NSNotification.Name(rawValue: "badge"), object: nil)
    }
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    if let secondController = secondController
    {
    NotificationCenter.default.removeObserver(CtrlB.self, name: NSNotification.Name(rawValue: "badge"), object: nil)
    }
}

//Also don't forget to remove listening on deinit

deinit
{
    if let secondController = secondController
    {
    NotificationCenter.default.removeObserver(secondController, name: NSNotification.Name(rawValue: "badge"), object: nil)
    }
  }
}

    class CtrlB: UIViewController {
        //Here you go with notification...
        static func badge (notification: NSNotification) {
            // blah blah
        }
    }

您需要获取观察器的实例,但尚未声明该实例

例如,您需要设置类变量secondA

class CtrlA: UIViewController {

var secondController: CtrlB?


override func viewDidLoad()
{
super.viewDidLoad()

    if let unwrappedController = storyboard.instantiateViewController(withIdentifier: "someViewController") as? CtrlB
    {
    secondController = unwrappedController        
    }

}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    if let secondController = secondController
    {
    NotificationCenter.default.addObserver(CtrlB.self, selector: #selector(CtrlB.badge(notification:)), name: NSNotification.Name(rawValue: "badge"), object: nil)
    }
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    if let secondController = secondController
    {
    NotificationCenter.default.removeObserver(CtrlB.self, name: NSNotification.Name(rawValue: "badge"), object: nil)
    }
}

//Also don't forget to remove listening on deinit

deinit
{
    if let secondController = secondController
    {
    NotificationCenter.default.removeObserver(secondController, name: NSNotification.Name(rawValue: "badge"), object: nil)
    }
  }
}

    class CtrlB: UIViewController {
        //Here you go with notification...
        static func badge (notification: NSNotification) {
            // blah blah
        }
    }
因此,在项目中实现通知的最佳方法是在声明一个字典的内部创建一个名为
NotificationManager
的类,您可以在其中随时更新观察者

创建addObserver方法、post通知方法和remove 同一类中的observer方法

因此,在您的任何类中,只要需要,就可以访问上面的方法,它会处理所有问题。这也将防止代码崩溃。如果尝试多次删除同一观察者

因此,在项目中实现通知的最佳方法是在声明一个字典的内部创建一个名为
NotificationManager
的类,您可以在其中随时更新观察者

创建addObserver方法、post通知方法和remove 同一类中的observer方法

因此,在您的任何类中,只要需要,就可以访问上面的方法,它会处理所有问题。这也将防止代码崩溃。如果尝试多次删除同一观察者



您可以只使用
NotificationCenter.default.removeObserver(self)
,它将删除当前类中的所有观察者。您可以只使用
NotificationCenter.default.removeObserver(self)
,它将删除当前类中的所有观察者。在不指向具有标识符的nib/storyboard viewController的情况下实例化控制器将导致崩溃。另外,不建议在类级别实例化变量。@DominikBucher它不会导致崩溃。关于类级别上的变量,您是对的(有点),但这是一个如何正确注册/取消注册的通用示例,所以我猜我是如何声明常数的并不重要。好吧,那么常数如何知道使用哪个nib并正确关联iboutlets?@DominikBucher UIViewController可以没有nib,也没有与之关联的iboutlets。这就是为什么UIViewController类中有一个没有参数的构造函数。实例化控制器而不指向具有标识符的nib/storyboard viewController会导致崩溃。另外,不建议在类级别实例化变量。@DominikBucher它不会导致崩溃。关于类级别上的变量,您是对的(有点),但这是一个如何正确注册/取消注册的通用示例,所以我猜我是如何声明常数的并不重要。好吧,那么常数如何知道使用哪个nib并正确关联iboutlets?@DominikBucher UIViewController可以没有nib,也没有与之关联的iboutlets。这就是为什么UIViewController类中有一个没有参数的构造函数。我自己使用通知管理器。这是非常好的,因为它将妥善清理一切,当它是交易。虽然我使用了一个NSObjectProtocol数组来存储观察者。从这一行
guard let observer=self.observer[name]else{return}
我想你的意思是:
guard let observer=self.observer dict[name]else{return}
对吗@侯赛因:是的,我想还有一件事,你通常怎么用这个?我想你必须在你想使用的任何类中创建一个实例,这意味着每个实例都有一个不同的观察者字典,可以吗?如果observer字典和函数都是静态的,那不是更好吗?在我们的项目中,我们创建了任何需要的类的实例。但这取决于你的需求,你可以如何管理。我自己使用通知管理器。这是非常好的,因为它将妥善清理一切,当它是交易。虽然我使用了一个NSObjectProtocol数组来存储观察者。从这一行
guard let observer=self.observer[name]else{return}
我想你的意思是:
guard let observer=self.observer dict[name]else{return}
对吗@侯赛因:是的,我想还有一件事,你通常怎么用这个?我想你必须在你想使用的任何类中创建一个实例,这意味着每个实例都有一个不同的观察者字典,可以吗?如果observer字典和函数都是静态的,那不是更好吗?在我们的项目中,我们创建了任何需要的类的实例。但这取决于您的需求,以及您如何管理。