I am making a “custom class” that is only used inside a single ServerScript, and needed to make a custom event called Fired for it.
Because it doesn’t replicate to the client, I was going to simply use Instance.new("BindableEvent",script) and add a listener. But then I realized that, by doing this, I would create way too much clutter inside the script (I create a lot of this custom class).
My question is, is simply using self.Fired = Instance.new("BindableEvent") and never setting the parent going to cause problems (getting garbage collected when it’s not supposed to, not firing the event, etc.) or am I free to use this method?
And if this is okay, does self.Fired = Instance.new("BindableEvent").Event also work or do I have to, at least, save a reference to the BindableEvent instance?
EXAMPLE CODE:
local self = {}
self.Fired = Instance.new("BindableEvent")
self.Fired.Event:Connect(function()
print("Fired!")
end)
-- Or, in alternative:
local self = {}
self.Fired = Instance.new("BindableEvent").Event
self.Fired:Connect(function()
print("Fired!")
end)
I’m pretty sure it’s parent is set to nil, but it should work like a normal bindable event except that you cannot locate it with other scripts.
(*Also not that most “signal” modules that use bindable events do it like this, so it should be fine)
Historically this has never been an issue - orphaned Roblox Instances will stick around in memory forever. It’s part of why Remove was replaced with Destroy! This behavior is still present to this day, so your code should work exactly as you suspect!
That being said, I’d be very wary of taking advantage of this fact. Roblox could, at any point, decide to finally garbage collect fully-orphaned Instances and thus break your code. As it stands, your first example will almost certainly never break (as the self.Fired is a strong reference to the orphaned BindableEvent Instance, so it isn’t fully orphaned), but the second one could as the self.Fired reference is to a property of the Instance instead of the Instance itself. For the time being, though, this is perfectly safe code.
Personally, I’m a bit paranoid so I’d just create a Folder inside the ModuleScript containing all of the BindableEvents it creates, and use a combination of your two example so that the deconstructor for your class can Destroy them as necessary:
local self = {}
self.FiredBEInstance = Instance.new("BindableEvent", script.BEInstances) -- you're not actually modifying any property of the Instance, *and* this isn't being replicated anywhere, so this is fine for parenting it to the DataModel
self.Fired = self.FiredBEInstance.Event
...
self.Fired:Connect(function()
print("Fired!")
end)