这是一个困扰我一段时间的问题。我对其中一些模式仍然很新,所以如果我错误地使用任何一个术语,你将不得不原谅我(并纠正我)。
我的方法论
我创建了一个游戏引擎。我的游戏引擎中的所有对象都使用控制反转来获取依赖关系。这些依赖项都实现了协议,除了在引导阶段之外,永远不会直接在项目中访问。为了获得这些对象,我有一个服务定位器的概念。服务定位器的工作是找到符合特定协议的对象并将其返回。它很像工厂,但它也应该处理依赖关系。
为了向服务定位器提供服务,我有所谓的服务说明符。服务定位器知道项目中的所有服务说明符,并且在请求对象时,尝试从每个服务中获取符合所提供协议的对象实例。然后将此对象返回给调用者。这个设置的好处是服务说明符也知道服务定位器,所以如果它有任何依赖关系,它只是向服务定位器询问这些特定的依赖关系。
举个例子,我有一个名为HighScoreManager的对象。 HighScoreManager实现了PHighScoreManager协议。在任何时候如果需要PHighScoreManager的实例,可以通过调用:
来检索它id<PHighScoreManager> highScoreManager = [ServiceLocator resolve: @protocol(PHighScoreManager)];
因此,控制倒置。但是,大多数情况下甚至不需要这样做,因为大多数类都位于服务说明符中,如果需要PHighScoreManager作为依赖项,则通过服务定位器检索它。因此,我有一个很好的平面控制反转方法。
我的问题
因为我希望共享我的游戏引擎中的代码,所以我将它编译为静态库。这对其他一切都很棒,但似乎对服务定位器有点棘手。问题是一些服务在游戏到游戏的基础上发生了变化。在我上面的例子中,一个游戏中的得分可能是一个时间,而另一个游戏中的得分可能是积分。因此,HighScoreManager依赖于PHighScoreCreator的一个实例,它告诉它如何创建PScore目标。
为了向HighScoreManager提供PHighScoreCreator,我需要为我的游戏提供服务说明符。我能想到的唯一方法是使用Cocoa版本的反射。在挖掘之后,我发现通过NSBundle可以发现类,但似乎没有办法获得当前的包。因此,如果我想能够搜索我的服务说明符,我将必须将我的游戏逻辑编译到它自己的包中,然后让引擎搜索这个包并加载它。为了做到这一点,我必须创建第三个项目来容纳引擎代码和游戏逻辑包,而实际上我想要一个使用引擎静态库的游戏项目。
我的真实问题
所有这些之后,我的问题是
感谢您的帮助,并花时间阅读问题。
-helixed
答案 0 :(得分:1)
看看:
这些允许您在运行时以编程方式与各种bundle进行交互。一旦你有一个捆绑工作,你可以采用一些策略来找到你正在寻找的特定类。例如:
现在,您可以创建捆绑包作者提供的类的实例,该实例实现您指定的任何协议。
Objective-C运行时是一件很棒的事情!
答案 1 :(得分:1)
听起来你需要使用Objective-C runtime的功能。首先,您可以通过objc_getClassList
获取所有可用课程的列表。然后,您可以迭代所有类,并使用class_conformsToProtocol
检查它们是否符合您的协议。您不应在此处使用+conformsToProtocol:
消息,因为运行时中的类不支持此选择器。