对于2015年9月,以下是在Swift中创建单例的具体方法:
public class Model
{
static let shared = Model()
// ( for ocd friends ... private init() {} )
func test()->Double { print("yo") }
}
然后在别处...
blah blah
Model.shared.test()
没问题的。
然而,我加上一点...
public let model = Model.shared
public class Model
{
static let shared = Model()
func test()->Double { print("yo") }
}
然后,您只需在项目范围内执行以下操作:
blah blah
model.test()
约定俗成的成语:
您可以在代码中的任何地方看到Model.shared.blah()
。
“我的”成语:
您可以在代码中的任何地方看到model.blah()
。
所以,这导致一切看起来很漂亮!
这是一个“宏观式”的成语。
它的唯一目的是让代码看起来漂亮。
在整个项目中将ImportantSystem.SharedImportantSystem
的外观简化为importantSystem.
。
有人能看出这个成语有什么问题吗?
问题可以是技术性的、文体性的或任何其他类别的,只要它们真的很深。
作为一个随机的例子,这里有一篇“Swift中的单例文章”,碰巧也提出了这个想法:https://theswiftdev.com/swift-singleton-design-pattern/
3条答案
按热度按时间mwyxok5s1#
在功能上,它们非常相似,但我建议使用
Model.shared
语法,因为无论在哪里使用它,都非常清楚地表明您在处理单例,而如果您只是让model
全局变量浮动在那里,则无法清楚地了解您在处理什么。此外,使用全局变量(特别是使用简单的名称,如“model”),您可能会遇到将来的某个类具有类似名称的变量,并且意外地引用了错误的变量。
关于全局模式、单例模式和其他模式的一般性讨论,请参见Global Variables Are Bad,尽管标题相当领先,但它提供了一个冷静的讨论,有一些有趣的链接,并提供了替代方案。
顺便说一句,对于你的“强迫症朋友”(我想我必须把自己算在内,因为我认为这是最好的做法),不仅会把
init
声明为private
,而且你可能会把整个类声明为final
,以避免子类化(在这一点上,shared
引用的内容变得模棱两可)。gblwokeq2#
使用此方法时,需要注意以下几点:
全局变量
全局变量本身没什么大不了的,但是如果你有很多全局变量,你可能会在自动完成方面遇到麻烦,因为它总是会建议使用这些全局变量。
全局变量的另一个问题是你的应用程序中的另一个模块(由你或其他人编写)定义了相同的全局变量。这会导致两个模块一起使用时出现问题。这可以通过使用前缀来解决,比如你的应用程序的首字母。
使用全局变量通常被认为是不好的做法。
单例模式
单例在使用控制器或仓库时很有用。它一旦创建,就会创建它所依赖的一切。只能有一个控制器,并且它只打开一个到数据库的连接。这避免了在使用需要从整个应用访问的资源或变量时的许多麻烦。
但是也有缺点,比如可测试性。当一个类使用单例时,这个类的行为会受到单例行为的影响。
另一个可能的问题是线程安全。当从不同的线程访问一个单例而不加锁时,可能会出现难以调试的问题。
总结
在定义全局变量和使用单例时,你应该小心。只要小心,就不会出现太多问题。
6rvt4ljy3#
我看不出这种方法有任何缺点:
Model.shared.test()
真的没有意义,你只想调用测试,为什么我需要调用shared
,当我只需要一个函数的时候。总的来说,撇开讨论中的确切习语不谈,关于单例的使用:
static var shared = Model()
作为单例的一种宏不同,正如本Q中所建议的,您可以只定义let model = Model()
,它只是创建一个普通的全局变量(与单例无关)。private init() {}
,这样它只初始化一次(注意,init
仍然可以在同一个文件中被调用)。