何时在 Swift 中使用全局变量
Posted
技术标签:
【中文标题】何时在 Swift 中使用全局变量【英文标题】:When to use global variables in Swift 【发布时间】:2015-12-26 22:40:38 【问题描述】:我正在学习 Swift 和 ios 应用程序开发,我想知道在哪些情况下(如果有的话)我应该在 iOS 应用程序中使用全局变量和常量。
全局变量是在任何函数、方法、闭包或类型上下文之外定义的变量。局部变量是在函数、方法或闭包上下文中定义的变量。
使用全局变量通常看起来不优雅且不可取(实际上大多数指南和教程都不推荐)并且在视图控制器之间传递数据我使用prepareForSegue(_: sender:)
方法。
在某些情况下,在我看来,使用全局变量会使代码更简单、更快。
例如,Apple 建议为每种格式模式存储 NSDateFormatter
或 NSNumberFormatter
,而不是在每次需要时重新创建或更改。在我为学习该语言而开发的应用程序中,大多数视图控制器使用NSDateFormatter
和NSNumberFormatter
,并且为每个视图控制器创建一个新的视图控制器可能不是一个好主意。我可以使用 prepareForSegue 传递它,但我认为在这种情况下,最好使用一个全局变量来保存每个视图控制器都可以使用的格式化程序实例。
那么在某些情况下我应该使用全局变量吗?
【问题讨论】:
我不这么认为。即使对于您提供的示例,您也可以将这些格式化程序“存储”为单例Settings
的属性。甚至调用命名的单例你也不能通过全局常量,而是通过类的静态属性。
是的,当你想在swift中为一个类创建一个类变量时,你需要使用一个全局的。一旦 swift 支持类变量,除非您需要提高性能,否则真的没有理由使用全局变量
全局变量很方便,但通常应避免使用。谷歌“globals are evil”,你会发现很多关于它为什么不好、替代方案等的讨论。不幸的是,这个问题 (a) 已经在这里讨论过很多次了;并且(b)无论如何都是一个意见问题,所以这个问题应该被关闭。
@Knight0fDragon Swift 的 static var
不能作为类变量工作吗?
@Lorenzo Rossi,他们什么时候开始允许在类中使用静态变量,为什么他们仍然不支持类变量,除了作为没有内置存储数据的属性,我发誓我不了解正在进行的思考过程。我会说区别在于类变量是属性变量,但似乎静态变量也可以是属性。好吧,既然它们允许在一个类中使用静态变量,那么为了提高效率就不需要全局变量
【参考方案1】:
每次您发现自己在使用全局变量时,都需要退后一步,认真思考数据是什么以及它与应用程序其他部分的关系。说你需要避免全局变量很容易,困难的部分是知道该场景的最佳替代方案,即使是资深的 Cocoa 开发人员也会不同意。
在单例模式中,您创建一个类并将全局存储在其中。这通常作为解决方案提供,因为它最容易开处方和遵循,但很多时候我想知道它是否是一个解决方案。围绕全局包装一个类不会给你任何额外的保护。毕竟,类本身现在是一个全局实体。我喜欢将单例模式视为一种组织、分类和包含全局变量的方式,而不是避免使用全局变量。
应该为应用程序的支柱保留单例,例如数据库或远程后端连接处理程序。每个 Cocoa/CocoaTouch 应用程序都带有一个内置的 Singleton,即 AppDelegate,并且在许多情况下,各种各样的东西都可以放在那里。
在许多情况下,“正确”的解决方案是传递数据,例如在prepareForSegue:
类中的视图控制器之间传递数据。这在 Andy Matuschak 精彩的 WWDC 2014 会议Advanced iOS Application Architecture and Patterns 中有很好的描述。不过,我同意您的观点,这不适用于您的示例。在您的示例中,您不是在两个视图之间处理相关数据,而是尝试共享一个公共设施以节省资源。
对于您的具体示例,我将使用 Singleton 或类似模式。对我来说有意义的一种方法是使用扩展将它们存储在相应的类中。例如:
extension NSDateFormatter
static let newDateFormatter = NSDateFormatter()
// use it in your app like this:
NSDateFormatter.newDateFormatter
正如评论者所说,这是一个见仁见智的问题。还要记住,Swift 还很年轻,虽然它出于需要大量借鉴了 Cocoa,但成语仍在不断发展。
【讨论】:
我无法理解 Cocoa 框架似乎强迫你在一个类中编写整个应用程序似乎这是我经历过的最愚蠢的事情我根本无法拥有自己的结构、类和包以上是关于何时在 Swift 中使用全局变量的主要内容,如果未能解决你的问题,请参考以下文章