什么是这种设计模式,其中方法是实例方法而不是类方法?

时间:2016-02-06 00:40:33

标签: ios objective-c design-patterns

 NSData *_dataArchive = [[NSUserDefaults standardUserDefaults] 
                                        objectForKey:@"Session"];

这种风格在Obj-C中很常见。

为什么[[NSUserDefaults standardUserDefaults] someMethod]?这里someMethod是InstanceMethod?

为什么不[NSUserDefaults someMethod]?这里someMethod是Class方法。

4 个答案:

答案 0 :(得分:4)

您的困惑可能是您认为只能有一个NSUserDefaults。事实并非如此。 NSUserDefaults的原始设计包括使用initWithUser:获取特定用户的默认值的功能。这从未实现过(现已弃用),但它展示了如果使用类方法设计你将面临的限制。

在最新的基金会中,有一个新的initWithSuiteName:可用于在相关应用程序之间共享默认值。所以很高兴我们没有这个限制,即使实际使用了几十年。

这里有一个重要的教训,就是设计自己的API。一般来说,最好是容易访问的实例(“共享......”等),而不是强制一个你永远无法扩展的实例。

答案 1 :(得分:3)

它不是一种设计模式。它只是您在对象实例上调用方法的正常方式。

以这种方式思考代码:

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSDate *dataArchive = [defaults objectForKey:@"Session"];

这只是一种正常的方法调用。

它不是[NSUserDefaults someMethod]因为objectForKey:需要在NSUserDefaults的特定实例上调用。

答案 2 :(得分:2)

这里的关键问题是拥有一堆类方法不如单个共享实例的一堆实例方法灵活。如果您随后决定要允许多个实例,该怎么办?在这个共享实例模式中,这是微不足道的,但在类方法方法中,它可能需要相当多的重构。此外,在这种情况下,我们可以重置标准用户默认值,这在已发布的共享实例的上下文中有点直观,但在没有任何实例的类的情况下则不太清楚。究竟是什么重置?

就此模式的名称而言,standardUserDefaults返回的此共享实例与单例模式非常相似。事实上,类方法与共享实例的实例方法的争论通常在单例的上下文中讨论,单例是具有单个共享实例的类的原型示例。但是NSUserDefaults偏离单身模式(部分原因是Rob Napier讨论的原因,也因为单身人士没有考虑他们的释放,resetStandardUserDefaults可以做到)。这种特定的NSUserDefaults模式没有一个普遍接受的名称(超出一些非正式的名称,例如“可重置的共享实例”)。

所以,如果你正在寻找更多关于这两种方法的利弊的信息,我建议我们少关注NSUserDefaults的特殊细节:我建议你搜索“单身人士” vs class methods“你可以找到Singleton Instance vs Class Methods等链接。

答案 3 :(得分:2)

在阅读完最后两个问题后,我得到的印象是您并未完全了解Singletons

Singleton设计模式是在制作应用程序时广泛使用的各种用例模式(例如,维护当前登录用户的登录会话和数据等)。在此模式中,您创建一个类并以特定的方式对其进行初始化,以便可以创建一个且仅一个实例。因此,当您第一次初始化NSUserDefaults *abc = [NSUserDefaults standardUserDefaults]时,会在内存中创建类NSUserDefaults的实例/对象。现在,当你在第一个之后进行任何初始化时,比如NSUserDefaults *xyz = [NSUserDefaults standardUserDefaults],而不是创建类NSUserDefaults的新实例,则返回已经创建的实例。因此,abcxyz都将在内存中保存相同的实例;两者都不代表两个单独的实例。

解决您对方法的关注,因此,方法objectForKey:是在对象实例上调用的实例方法。因此,您首先通过[NSUserDefaults standardUserDefaults]获取单例实例,然后在此实例上调用该方法。