This should be in #bug-reports but I lack the access to it.
I found out that events do not disconnect even after calling the :Disconnect() function. You may reproduce the bug using the steps below:
Create any place.
Make an event connection in any script (I use a server script with the following code parented under Baseplate part in Classic Baseplate place).
local con = script.Parent.Touched:Connect(function()
print("")
end)
print(con) --> Should print a Connection instance
con:Disconnect()
print(con)-- Still prints it?
Run the game and check the output.
What should be expected
When the event disconnects, it the con variable should be nil.
What it actually gives
Even after disconnecting the event, the con variable still contains the Connection instance value.
I’ve checked the watch debugger, and it seems that the con variable still contains a value even after the event is disconnected.
Is this an intentional feature or a bug? If it is the former, may I know why it is intentional?
Thanks.
Disconnecting a RBXScriptConnection will not remove your reference to it and this is intended. You should also set the reference to nil to get intended behavior.
Actually an event that is disconnected, but there is still a strong reference to, will not be garbage collected. You can see this by putting this example in a script in workspace.
--This part just ensures garbage collection runs
function setupGarbageCollection()
local test = {}
for i = 1, 10000000, 1 do
test[i] = true
end
end
--Now actually try garbage collection
local strongTable = {workspace.AncestryChanged:Connect(function() print("Changed!") end)}
--Create a weak table in order to drop values if they are garbage collected
local weakTable = setmetatable({}, {__mode = "v"})
weakTable[1] = strongTable[1]
--Let garbage collection run as a test
setupGarbageCollection()
task.wait(2)
print(#weakTable) --Outputs 1
--Disconnect value
weakTable[1]:Disconnect()
--Check if garbage collected!
setupGarbageCollection()
task.wait(2)
print(#weakTable) --Outputs 1, was not garbage collected
--Remove all references
strongTable[1] = nil
--Check if garabge collected!
setupGarbageCollection()
task.wait(2)
print(#weakTable) --Outputs 0, was garbage collected!
So as long as con is still defined in the script as a reference, the connection will not be garbage collected. Setting con to nil though will make the connection be garbage collected, like shown in the post you’ve linked.
Thanks for your reply. So does that mean I have to manually set every variable which contains an event connection to nil after calling :Disconnect() to ensure the variable is fully GC’ed?
There are some cases where you don’t have to, but honestly if you don’t know the few specific cases, and even if you do, I would just be on the side of caution and say yes. You should set all variables to nil that contains connections to be fully garbage collected.