I was writing new Shop UI and coding it and had a brain moment it stumbled upon me that my old code for Settings e.t.c can have a possible memory leak. Heres the Settings Code (Exit Button).
local tween = TweenService:Create(self.MainFrame, tweenInfo, {Position = UDim2.new(0.5,0,-.5,0)})
tween:Play()
tween.Completed:Connect(function()
self.MainFrame.Visible = false
end)
The connection is never disconnected UNLESS TweenService automatically disconnects it when completed is done. or would this new Shop code have no memory leaks here is the closing button
self.MainFrame.Exit.Button.MouseButton1Click:Connect(function()
local tween = TweenService:Create(self.MainFrame, TweenInfo.new(.5, Enum.EasingStyle.Quad, Enum.EasingDirection.Out), {Position = UDim2.new(0.5,0,.5,0)})
tween:Play()
self._closingTween = tween.Completed:Connect(function()
self.MainFrame.Visible = false
self._closingTween = nil
end)
self.MainFrame.Visible = false
end)
Is it good that I noticed this early on if it is a possible memory leak? I assume so, just want to be sure and hear from someone who may know. Thank you and looking at it now im going to make this a Util module script for basic UI handling. 
1 Like
Yeah, Good catch!
Tween.Completed:Connect
won’t auto disconnect, so if you fire tweens repeatedly you’ll leak connections. Either call connection:Disconnect()
inside your callback or use tween.Completed:Wait()
and yes, pulling that logic into a UI util module is a smart refactor 
2 Likes
why not just use :Once()
?
1 Like
you’re totally right, overlooked that. :Once()
tween:Play()
tween.Completed:Once(function()
self.MainFrame.Visible = false
end)
Thank you for replying! I’ll refactor my code to use Utils which is a lot cleaner haha
1 Like
Not quite. Roblox will automatically disconnect the connection once the tween object is collected from memory. You can observe this using the following code sample:
local function f()
local tween = game:GetService("TweenService"):Create(Instance.new("Part"), TweenInfo.new(2), { CFrame = CFrame.identity })
local connection = tween.Completed:Connect(function(playbackState: Enum.PlaybackState) end)
return connection
end
local connection = f()
while task.wait() do
print(connection.Connected)
end
On the sample, f
is called (not inlined (although it wouldn’t matter anyway)), and connection.Connected
will become false
after a while; you needn’t worry about the connection in this case; the engine would handle it for you

2 Likes