If cleaning a target node that has a listener in the 'to be added' listeners list then ensure that listener does not have a stale reference to the node. This is a minor tweak in addition to pull request 6160 (https://github.com/cocos2d/cocos2d-x/pull/6160).
Fix possible crashes which could be caused by the EventDispatcher having listeners associated with nodes are destroyed. Catch the case where a node registers a listener while we are dispatching events and gets destroyed while that event is still being dispatched. Check the list of nodes to be added into the event dispatcher fully when we are cleaning listeners for a target node.
This issue was found using the extra debug verification in this pull request:
https://github.com/cocos2d/cocos2d-x/pull/6011
Always safe release the listener we retain - shift where release happens to the end of the block. Reproduced the leak using the Xcode Leaks instrument in the RemoveListenerAfterAddingTest and verified fixed after apply this change.
1: Add a fix to prevent events from being sent to scene nodes which are destroyed. Previously when a node was being destroyed it would try to unregister any event listeners it would have. This process would fail however in the case where event dispatching was already underway because we can't modify the listeners list while we are iterating through it. This is a pretty common occurrence since we often tear down & switch scenes in response to button clicks etc. Fix the problem by nulling out the slot for the listener we are removing in this case, so that it's node no longer receives any events after it is destroyed. The event dispatching code will cleanup this unused/nulled slot once the event processing loop has terminated.
2: When removing an event listener in cocos2d::EventDispatcher, ensure immediately it gets removed from the node priority map and dirty nodes set in order to ensure we don't inadvertently access any dangling pointers to nodes.
3: Add debug checks to ensure nodes have no associated event listeners after they are destroyed. This check will catch the problem fixed by (1) if it is still present.
4: Add some extra debug sanity checks in the event dispatcher to ensure nodes are not added to the lists twice and that they are being properly removed from the lists under certain conditions.
5: In cocos2d::Node's destructor NULL out members after releasing them in case they somehow happen to be accessed during the destructor. Move the release of the event dispatcher to the very end, since we need to check against it in debug.