你从问题开始:
有没有办法让aThing 在运行时知道它是ThingManager 的属性?
虽然到目前为止还没有完全清楚答案,但假设您希望aThing 能够确定ThingManger 的一个实例 是否正在管理它。
所以此时我们知道ThingManger 类知道Thing 类,而您现在似乎想要反过来——您问Thing 可以找到它的ThingManager 吗?
但是当有人回答你评论时
所以Thing 和ThingManager 需要相互了解?嗯……不适合松耦合。
嗯...如果您不想让ThingManagers 知道Thing 是什么,Thing 怎么能问它?
每个人对你的问题的解释都错了吗?
也许您关心的不是松散耦合,而是强引用循环?如果两者相互了解,并在此过程中形成一个强大的循环,那么在您的应用程序需要其中任何一个之后,他们就有可能让彼此存活很长时间 - 这是担心吗?
但是@DrummerB 解决了这个问题——你在Thing 上使用了一个弱属性,它引用了它的管理ThingManager。所以看起来强参考周期也不是你关心的问题......
然后你评论:
有没有办法在运行时查看谁在引用对象?
正如一般所说,这是一个非常不同的问题。对此的简短回答是否定的[*]。
您是否问是否可以编写一个方法,Thing 可以调用该方法来查找管理它的ThingManager,而无需在Thing 实例和ThingManager 实例之间维护任何引用?
如果是这样,这里是一个大纲算法:
- 让
ThingManager 类保留所有创建和活动 实例的集合。活着的要求要求这个集合是某种弱集合(设计你自己的或搜索弱集合)。
- 向
ThingManager 添加一个class 方法,用于查找Thing 的管理器,例如类似+ (ThingManager *) managerFor:(Thing *)thing。
- 当您的
Thing 实例需要了解他们的经理时,请致电[ThingManager managerFor:self]。
这当然不能解决您对松散耦合的担忧——这两个类仍然必须知道彼此的存在......
这让您回到让Thing 拥有manager 属性的直接解决方案。如果您想减少耦合,您可以将此属性键入为id,因此它是任何旧对象,或id<SomeMinimalManagerProtocol>,因此它的任何旧对象提供它实现您在协议@987654351 中定义的一些最小管理方法集@。
看看NSWindow 和NSWindowController - 他们了解彼此。
HTH
[*] 长答案是 (Objective-)C(++) 并非旨在确保可以找到所有引用。这就是为什么您会听到诸如“保守垃圾收集”之类的短语。有一个仅针对 Objective-C 对象的垃圾收集器,它由运行时的内部更改支持,但现在已弃用,并且应用程序无法轻松访问其机制以应用于其他用途。