简体   繁体   English

NotificationCenter:Notification postet时的BAD_ACCESS

[英]NotificationCenter: BAD_ACCESS when Notification postet

I have an app with 3 viewcontrollers that are pushed on a navigation controller stack. 我有一个带有3个viewcontrollers的应用程序,它们被推送到导航控制器堆栈上。

(A) -> (B) -> (C)

(A) registers for notifications in viewWillAppear : (A)viewWillAppear注册通知:

NotificationCenter.default.addObserver(self, selector: #selector(reload), name: NSNotification.Name(rawValue: "DATA_CHANGED"), object: nil)

and (A ) deregisters in viewWillDisappear : (A )在viewWillDisappear取消注册:

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

Additionally (A) deregisters in deinit() but this is never called. 另外(A) deinit() (A)注销,但从未调用过。

Now (B) is pushed on stack and registers /deregisters for the same event like (A) . 现在(B)被推入堆栈并注册/注销同一事件,如(A)

Now (C) is pushed on stack that triggers a computation and pops back to (B) . 现在(C)被推入堆栈,触发计算并弹回(B) Some time later while (B) is presented the computation is finished and a Notification is fired: 一段时间后(B)显示计算完成并触发通知:

NotificationCenter.default.post(name: NSNotification.Name(rawValue: "DATA_CHANGED"), object: nil)

But this results in an 但这导致了一个

Thread 1: EXC_BAD_ACCESS 线程1:EXC_BAD_ACCESS

I'm sure that the notification is the problem because i misspelled the notification name and then no crash occurred. 我确定通知是问题,因为我拼错了通知名称,然后没有发生崩溃。 Also (A) and (B) are still not deallocated as the are living on the stack. 此外, (A)(B)仍然没有被释放,因为它们生活在堆叠上。 I could not find any Zombie in Profiler. 我在Profiler中找不到任何Zombie。

Any idea what might be the problem? 知道可能是什么问题吗?

I'm using XCode 9beta6 and Swift 4. 我正在使用XCode 9beta6和Swift 4。

So I just spent about 4 hours fixing this in my own code. 所以我花了大约4个小时来修复我自己的代码。 Here is what my problem was: 这是我的问题所在:

The function I specified in my selector had an optional parameter with a default value of nil. 我在选择器中指定的函数有一个可选参数,默认值为nil。 My selector then looked just like yours - no parameter list. 我的选择器看起来就像你的 - 没有参数列表。 However, when I was firing a notification, I was getting EXC_BAD_ACCESS. 但是,当我发出通知时,我得到了EXC_BAD_ACCESS。

I was trying to call a parent's function with my selector in relation to the child class I was registering the notification on. 我试图用我的选择器调用父项的函数与我正在注册通知的子类相关。 I had to make a helper function on the child class and call the parent's function. 我必须在子类上创建一个辅助函数并调用父函数。

If you have an optional parameter in reload and/or reload is a function in a parent class, try making a helper function which calls reload and make your selector point to that. 如果在重新加载时有一个可选参数和/或重载是父类中的一个函数,请尝试创建一个调用reload的辅助函数,并使选择器指向该函数。

您正在注册名称为“BACKEND_DATA_CHANGED”的通知并取消注册“DATA_CHANGED”。它们是不同的通知。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM