swift2 在Swift中不使用单例“变量”有什么原因吗?

vyswwuz2  于 2022-11-06  发布在  Swift
关注(0)|答案(3)|浏览(157)

对于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/

mwyxok5s

mwyxok5s1#

在功能上,它们非常相似,但我建议使用Model.shared语法,因为无论在哪里使用它,都非常清楚地表明您在处理单例,而如果您只是让model全局变量浮动在那里,则无法清楚地了解您在处理什么。
此外,使用全局变量(特别是使用简单的名称,如“model”),您可能会遇到将来的某个类具有类似名称的变量,并且意外地引用了错误的变量。
关于全局模式、单例模式和其他模式的一般性讨论,请参见Global Variables Are Bad,尽管标题相当领先,但它提供了一个冷静的讨论,有一些有趣的链接,并提供了替代方案。
顺便说一句,对于你的“强迫症朋友”(我想我必须把自己算在内,因为我认为这是最好的做法),不仅会把init声明为private,而且你可能会把整个类声明为final,以避免子类化(在这一点上,shared引用的内容变得模棱两可)。

gblwokeq

gblwokeq2#

使用此方法时,需要注意以下几点:

全局变量

全局变量本身没什么大不了的,但是如果你有很多全局变量,你可能会在自动完成方面遇到麻烦,因为它总是会建议使用这些全局变量。
全局变量的另一个问题是你的应用程序中的另一个模块(由你或其他人编写)定义了相同的全局变量。这会导致两个模块一起使用时出现问题。这可以通过使用前缀来解决,比如你的应用程序的首字母。
使用全局变量通常被认为是不好的做法。

单例模式

单例在使用控制器或仓库时很有用。它一旦创建,就会创建它所依赖的一切。只能有一个控制器,并且它只打开一个到数据库的连接。这避免了在使用需要从整个应用访问的资源或变量时的许多麻烦。
但是也有缺点,比如可测试性。当一个类使用单例时,这个类的行为会受到单例行为的影响。
另一个可能的问题是线程安全。当从不同的线程访问一个单例而不加锁时,可能会出现难以调试的问题。

总结

在定义全局变量和使用单例时,你应该小心。只要小心,就不会出现太多问题。

6rvt4ljy

6rvt4ljy3#

我看不出这种方法有任何缺点:

  • 你可以为程序的不同部分使用不同的变量(-〉如果你不喜欢的话,我猜没有名字空间填充)
  • 它很短,很漂亮,很容易使用,当你读它的时候很有意义。如果你想一想,Model.shared.test()真的没有意义,你只想调用测试,为什么我需要调用shared,当我只需要一个函数的时候。
  • 它使用Swift的惰性全局命名空间:当您第一次使用该类时,它将被分配和初始化;如果您从不使用它,它甚至不会被分配/初始化。

总的来说,撇开讨论中的确切习语不谈,关于单例的使用:

  • 回想一下,当然,与使用static var shared = Model()作为单例的一种宏不同,正如本Q中所建议的,您可以只定义let model = Model(),它只是创建一个普通的全局变量(与单例无关)。
  • 对于Swift singletons,曾经有过这样的讨论:您可能希望向类中添加一个private init() {},这样它只初始化一次(注意,init仍然可以在同一个文件中被调用)。
  • 当然,一般来说,当考虑使用单例时,如果你并不真正需要状态和类示例本身,你可以简单地使用静态函数/属性来代替。使用单例(比如“类似计算”的函数)是一个常见的错误,因为它所需要的只是一个静态方法。

相关问题