Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by DavidJares · Jul 22, 2018 at 02:06 PM · monobehaviourclassesreferences

How to get a reference to the owner-Script from inside a Class which is being used as field/property

Hello. I am creating a class - lets call it Foo ( not Monobehaviour ) which then will be used on Monobehaviours - lets call them Bar - as a field/ or Property. Is it possible to somehow get a reference from Foo to Bar ? Maybe with reflection or something like that ?

Particularly, I would like to keep a static list/ Set of Monobehaviours inside Foo which is a collection of all Monobehaviours which do use Foo somewhere on some of their Scripts.

Thank you in advance for any answers.

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by JVene · Jul 22, 2018 at 11:47 PM

There is no automatic means, no reflection service to ask for the owner of the references. You have to build that yourself. The initialization of a new Foo, for example, could take a reference to the "this" of Bar when the Foo is allocated, and store it. Foo would "know" the Bar that owns it. Similarly, a static registry can be built (a container) of all the Foos that Bars have, but nothing does that automatically.

However, you have to be mindful of potential circular references with this kind of design. If Bar uses a reference to own a Foo, and Foo has a reference to the Bar, who let's go first?

Circular references also have a compile time meaning, where one class requires the other, and the reverse at the same time. This should be avoided in the first place, and there are almost always better design choices that avoid this. You can get into that mess because you start down that road.

However, the circular reference I'm talking about is about storage, not compilation dependency.

References in C# are reference counted smart pointers under the hood. This allows several objects to consume a common Foo without concern for who is last to hold that Foo (the reference counter deals with that for you). The problem comes when that Foo also hold such a reference to the Bar. The Bar is owned by someone if it is instantiated (not a purely static class). As such, something has a reference to the Bar (as a MonoBehaviour derivative, it is owned by the Unity framework through some reference that holds it). If Unity clears all content, the Bar is expected to disappear, but the Foo that is holding it keeps holding it, and the Bar, holding that Foo, has not explicitly let go of the Foo - they are holding each other, the definition of circular reference in this context.

They will "float away", bonded to each other, but nothing else in code will have reference to them. This is a memory leak, by design.

Some mechanism has to exist to break such a tie, or the design fails.

We have to ask, then why create a circular reference. They are nuisance to such an extent that when they occur it brings into question what design caused it. Why is it important enough to have the circular reference that any machinations should be expended to carefully break the circular reference at the appropriate time?

There are design patterns specifically aimed at dealing with this, but unfortunately C# doesn't directly employ some of them. In C++, for example, the shared_ptr has a weak_ptr counterpart which is used precisely for this circumstance. I don't know of a counterpart in C#.

You can simply ensure that one breaks before the other. When Bar is shut down, it can explicitly remove the Foo while clearing Foo's reference to the Bar, managing the problem.

C# is not particularly strong on this point because it lacks a deterministic destructor, and therefore can't participate in RAII designs where this connection or shutdown of an object should occur at a specific, determined moment (like destruction).

You can look into finalize, and it can "do" in a pinch, but it isn't guaranteed to execute at the moment Bar is actually done with Foo. It happens when GC gets around to clearing Bar out of memory.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image DavidJares · Jul 23, 2018 at 04:41 PM 1
Share

Thank you very much for that indepth explenation. Definitely a fiew new pieces of wisdom you brought to me here. Hope this exhaustive answer will help others too. I found a solution now without circular references for my problem. Not as elegant as it would have been with weak references , but good enough. Thank you very much.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

87 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Monobehavior vs other classes? 1 Answer

How to structure code for squad selection and movement 0 Answers

Classes : extend MonoBehaviour issues 1 Answer

Accessing Monobehaviour classes on other objects 1 Answer

Unity problems with classes C# 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges