何时在Swift中使用全局变量

时间:2021-12-21 16:51:35

I'm learning Swift and iOS app development and I was wondering in which cases (if there are some) I should use global variables and constants in an iOS app.

我正在学习Swift和iOS应用程序开发,我想知道在哪些情况下(如果有的话)我应该在iOS应用程序中使用全局变量和常量。

Global variables are variables that are defined outside of any function, method, closure, or type context. Local variables are variables that are defined within a function, method, or closure context.

全局变量是在任何函数,方法,闭包或类型上下文之外定义的变量。局部变量是在函数,方法或闭包上下文中定义的变量。

Using global variables usually seems inelegant and not advisable (it is in fact not recommended by most guides and tutorials) and to pass data between view controller I use the prepareForSegue(_: sender:) method.

使用全局变量通常看起来不优雅且不可取(实际上大多数指南和教程都不推荐)并且在视图控制器之间传递数据我使用prepareForSegue(_:sender :)方法。

There are some cases however where it seems to me that the use of globals would make the code simpler and faster.

在某些情况下,在我看来,使用全局变量会使代码更简单,更快。

For example Apple recommends to store a NSDateFormatter or a NSNumberFormatter for each format pattern and not to recreate or to change one every time it is needed. In an app I'm developing to learn the language, most of the view controllers use a NSDateFormatter and a NSNumberFormatter and creating a new one for each view controller might not be a good idea. I could pass it with prepareForSegue, but I thought that maybe in this case it would be better to use a global var holding an instance of the formatter that every view controller could use.

例如,Apple建议为每种格式模式存储NSDateFormatter或NSNumberFormatter,而不是每次需要时重新创建或更改一个格式模式。在我正在开发学习语言的应用程序中,大多数视图控制器使用NSDateFormatter和NSNumberFormatter,并为每个视图控制器创建一个新的可能不是一个好主意。我可以通过prepareForSegue传递它,但我想也许在这种情况下,最好使用一个全局var来保存每个视图控制器都可以使用的格式化程序实例。

So are there any cases where I should use global variables?

那么我是否应该使用全局变量?

1 个解决方案

#1


7  

Every time you find yourself using a global, you need to take a step back and think hard about what the data is and how it relates to the rest of your app. It is easy to say you need to avoid globals, the hard part is knowing the best alternative for the scenario, something even veteran Cocoa developers will disagree on.

每当您发现自己使用全局时,您需要退后一步,仔细思考数据是什么以及它与应用程序其余部分的关系。很容易说你需要避免使用全局变量,困难的部分是知道场景的最佳替代方案,即使是经验丰富的Cocoa开发人员也不同意。

In the singleton pattern, you create a class and stash your global inside it. This is often offered as a solution because it's the easiest to prescribe and follow, but many times I wonder if it is a solution at all. Wrapping a class around a global doesn't give you any additional protections. After all, the class itself is now a global entity. I like to think of the Singleton pattern as a way of organizing, categorizing and containing globals as opposed to avoiding globals.

在单例模式中,您创建一个类并将其全局存储在其中。这通常作为解决方案提供,因为它是最容易开处方和遵循的,但很多时候我不知道它是否是一个解决方案。在全球范围内包装课程不会给你任何额外的保护。毕竟,班级本身现在是一个全球实体。我喜欢将Singleton模式看作是一种组织,分类和包含全局变量的方式,而不是避免使用全局变量。

Singletons should be reserved for the tentpoles of your application like database or remote backend connection handlers. Every Cocoa/CocoaTouch App comes with a built in Singleton, the AppDelegate, and in many cases, assorted things can go there.

应该为您的应用程序的帐篷保留单身人员,例如数据库或远程后端连接处理程序。每个Cocoa / CocoaTouch应用程序都带有一个内置的Singleton,AppDelegate,在很多情况下,各种各样的东西可以去那里。

In many cases, the "correct" solution is to pass the data along, such as passing data between view controllers in the prepareForSegue: class. This is well described in Andy Matuschak's brilliant WWDC 2014 session, Advanced iOS Application Architecture and Patterns. I agree with you though, that this doesn't apply in your example. In your example, you're not handing relevant data between two views, you're trying to share a common facility to conserver resources.

在许多情况下,“正确”的解决方案是传递数据,例如在prepareForSegue:类中的视图控制器之间传递数据。这在Andy Matuschak辉煌的WWDC 2014会议,高级iOS应用程序架构和模式中得到了很好的描述。我同意你的看法,这不适用于你的例子。在您的示例中,您没有在两个视图之间处理相关数据,而是尝试共享一个公共工具来保存资源。

For your specific example, I would use a Singleton or similar pattern. One way that makes sense to me is to stash them inside their corresponding classes using extensions. For example:

对于您的具体示例,我将使用Singleton或类似模式。对我来说有意义的一种方法是使用扩展将它们存储在相应的类中。例如:

extension NSDateFormatter {
  static let newDateFormatter = NSDateFormatter()
}

// use it in your app like this:
NSDateFormatter.newDateFormatter

Like commenters said, this is a matter of opinion. Also keep in mind that Swift is still young and while it borrows heavily from Cocoa out of necessity, idioms are still evolving.

像评论者说的那样,这是一个意见问题。还要记住,斯威夫特仍然很年轻,虽然它必然会从可可中大量借用,但成语仍在不断发展。

#1


7  

Every time you find yourself using a global, you need to take a step back and think hard about what the data is and how it relates to the rest of your app. It is easy to say you need to avoid globals, the hard part is knowing the best alternative for the scenario, something even veteran Cocoa developers will disagree on.

每当您发现自己使用全局时,您需要退后一步,仔细思考数据是什么以及它与应用程序其余部分的关系。很容易说你需要避免使用全局变量,困难的部分是知道场景的最佳替代方案,即使是经验丰富的Cocoa开发人员也不同意。

In the singleton pattern, you create a class and stash your global inside it. This is often offered as a solution because it's the easiest to prescribe and follow, but many times I wonder if it is a solution at all. Wrapping a class around a global doesn't give you any additional protections. After all, the class itself is now a global entity. I like to think of the Singleton pattern as a way of organizing, categorizing and containing globals as opposed to avoiding globals.

在单例模式中,您创建一个类并将其全局存储在其中。这通常作为解决方案提供,因为它是最容易开处方和遵循的,但很多时候我不知道它是否是一个解决方案。在全球范围内包装课程不会给你任何额外的保护。毕竟,班级本身现在是一个全球实体。我喜欢将Singleton模式看作是一种组织,分类和包含全局变量的方式,而不是避免使用全局变量。

Singletons should be reserved for the tentpoles of your application like database or remote backend connection handlers. Every Cocoa/CocoaTouch App comes with a built in Singleton, the AppDelegate, and in many cases, assorted things can go there.

应该为您的应用程序的帐篷保留单身人员,例如数据库或远程后端连接处理程序。每个Cocoa / CocoaTouch应用程序都带有一个内置的Singleton,AppDelegate,在很多情况下,各种各样的东西可以去那里。

In many cases, the "correct" solution is to pass the data along, such as passing data between view controllers in the prepareForSegue: class. This is well described in Andy Matuschak's brilliant WWDC 2014 session, Advanced iOS Application Architecture and Patterns. I agree with you though, that this doesn't apply in your example. In your example, you're not handing relevant data between two views, you're trying to share a common facility to conserver resources.

在许多情况下,“正确”的解决方案是传递数据,例如在prepareForSegue:类中的视图控制器之间传递数据。这在Andy Matuschak辉煌的WWDC 2014会议,高级iOS应用程序架构和模式中得到了很好的描述。我同意你的看法,这不适用于你的例子。在您的示例中,您没有在两个视图之间处理相关数据,而是尝试共享一个公共工具来保存资源。

For your specific example, I would use a Singleton or similar pattern. One way that makes sense to me is to stash them inside their corresponding classes using extensions. For example:

对于您的具体示例,我将使用Singleton或类似模式。对我来说有意义的一种方法是使用扩展将它们存储在相应的类中。例如:

extension NSDateFormatter {
  static let newDateFormatter = NSDateFormatter()
}

// use it in your app like this:
NSDateFormatter.newDateFormatter

Like commenters said, this is a matter of opinion. Also keep in mind that Swift is still young and while it borrows heavily from Cocoa out of necessity, idioms are still evolving.

像评论者说的那样,这是一个意见问题。还要记住,斯威夫特仍然很年轻,虽然它必然会从可可中大量借用,但成语仍在不断发展。