Why does :Destroy() lock the object after setting its parent to nil?

This has caused a good amount of headaches to me because I use :Destroy() to get rid of items by reflex as I never did Parent = nil a lot (context being that I sometimes do repetitive tasks through the command bar to semi-automate things), which when I accidentally delete the wrong thing, Studio cannot bring it back because :Destroy() locked them in place. What is the reason behind :Destroy() locking the objects?

When you call destroy, it disconnects any connections on any event on that instance (and its children), locks the parent, and sets the parent to nil.

Destroy is meant to be used when you no longer need an object and you’re not gonna have references to it anymore, destroy helps undo some memory leaks caused by some issues in the Lua / C boundary of instances.

Because of that, it locks the parent, because if it’s under game, it will never GC.

I’m personally all for a :DisconnectAll method in instances that only does the disconnecting part.

3 Likes

It would be useful if they made :Destroy() not lock the object when ran from a static environment like the command bar when in edit mode. Such accidents may sound silly but when they happen around valuable stuff it can be a catastrophe.

You can use :Remove. However, I’m not entirely sure if it’s deprecated. It essentially just does Parent = nil, and as far as I know it also does it to the children. However it doesn’t disconnect connections.

:Remove() just sets the parent to nil (and does the same for all its descendants.), no benefits of doing that when :Destroy() exists.
And yes - it’s deprecated, and unsafe in an unsynchronized thread.

1 Like
local part = Instance.new("Part")
part.Parent = workspace

part.AncestryChanged:Connect(function(child, parent)
	if not parent then
		print(child.Name.." is being destroyed.")
	end
end)

task.wait(5)
part:Destroy()

This isn’t a perfect method because:

  1. If the instance is already parented to nil and then was destroyed it wouldn’t fire.

  2. If the instance is just parented to nil it will fire even if it wasn’t destroyed.

The first issue can’t be fixed.

The second issue can be fixed by connecting a connection to any of that instance and checking if that connection is disconnected. If yes, the instance has been destroyed.

It’s nice to note the .Destroying event is now a thing. But I’m relatively sure it’s still disabled so it doesn’t fire.

I’ve seen very few, if any, circumstances where an instance is parented to nil before the instance method “:Destroy()” is called on it.

Similarly I’ve seen very few, if any, scenarios in which an instance is parented to nil and then parented elsewhere.

“.Destroying” does not yet fire (still in the works).