我有两个控制器
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, name: NSNotification.Name(rawValue: "badge"), object: nil)
我不认为我可以使用self
,因为它已在CtrlB.self
上注册
答案 0 :(得分:2)
我不确定您为什么要注册/取消注册具有类而非实例的通知。 ' CtrlB.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
}
}
答案 1 :(得分:2)
因此,在项目中实现通知的最佳方法是在里面创建一个名为
class NotificationManager { var observers = [String: AnyObject]() }
的类,声明一个字典,您可以随时更新观察者
func postNotification(_ name: String, userInfo: [AnyHashable: Any]? = nil) {
NotificationCenter.default.post(name: name, object: nil, userInfo: userInfo)
}
func addObserver(_ name: String, block: @escaping (Notification) -> Void) {
//if observer is already in place for this name, remove it
removeObserverForName(name)
let observer = NotificationCenter.default.addObserver(forName: name), object: nil, queue: OperationQueue.main, using: block)
self.observers[name] = observer
}
func removeObserver(_ name: name) {
guard let observer = self.observers[name] else { return }
NotificationCenter.default.removeObserver(observer)
self.observers.removeValue(forKey: name)
}
//Removes all observers
func removeAllObservers() {
for observer in self.observers.values {
NotificationCenter.default.removeObserver(observer)
}self.observers = [:]
}
创建addObserver方法,发布通知方法并删除 同一类中的观察者方法。
for x in range(gen_num+1):
print(gen_number,"\t\t",juveniles_pop,"\t\t",adults_pop,"\t\t",seniles_pop,"\t\t",juveniles_pop+adults_pop+seniles_pop)
gen_number+=1
seniles_pop = (seniles_pop * seniles_surv) + (adults_pop * adults_surv)
juveniles_pop1 = adults_pop * birth_rate
adults_pop = juveniles_pop * juveniles_surv
juveniles_pop = juveniles_pop1
因此,无论何处需要,都可以在任何一个类中访问上述方法,它将处理所有事情。这也可以防止代码崩溃。如果尝试多次删除同一个观察者。
答案 2 :(得分:1)
您需要获取观察者的实例,而您尚未声明...
例如,你需要设置类变量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
}
}