ios 什么时候在 Swift 中使用静态常量和变量?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37701187/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 09:17:58  来源:igfitidea点击:

When to use static constant and variable in Swift?

iosswiftvariablesstaticconstants

提问by Mike

There are some posts for how to write code for static constantand static variablein Swift. But it is not clear when to use static constantand static variablerather than constantand variable. Can someone explain?

有一些职位,如何编写代码static constantstatic variable斯威夫特。但不清楚何时使用static constantandstatic variable而不是constantand variable。有人可以解释一下吗?

回答by Luca Angeletti

When you define a static var/let into a class (or struct), that information will be shared among all the instances (or values).

当您将静态 var/let 定义到类(或结构)中时,该信息将在所有实例(或值)之间共享。

Sharing information

共享信息

class Animal {
    static var nums = 0

    init() {
        Animal.nums += 1
    }
}

let dog = Animal()
Animal.nums // 1
let cat = Animal()
Animal.nums // 2

As you can see here, I created 2 separate instances of Animalbut both do share the same static variable nums.

正如您在此处看到的,我创建了 2 个单独的实例,Animal但它们共享相同的静态变量nums

Singleton

单身人士

Often a static constant is used to adopt the Singleton pattern. In this case we want no more than 1 instance of a class to be allocated. To do that we save the reference to the shared instance inside a constant and we do hide the initializer.

通常使用静态常量来采用单例模式。在这种情况下,我们希望分配的类不超过 1 个实例。为此,我们将共享实例的引用保存在一个常量中,并隐藏了初始值设定项。

class Singleton {
    static let sharedInstance = Singleton()

    private init() { }

    func doSomething() { }
}

Now when we need the Singletoninstance we write

现在当我们需要Singleton我们编写的实例时

Singleton.sharedInstance.doSomething()
Singleton.sharedInstance.doSomething()
Singleton.sharedInstance.doSomething()

This approach does allow us to use always the same instance, even in different points of the app.

这种方法确实允许我们始终使用相同的实例,即使在应用程序的不同点也是如此。

回答by Dari

There are some posts for how to write code for static constant and static variable in Swift. But it is not clear when to use static constant and static variable rather than constant and variable. Can someone explain? When you define a static var/let into a class (or struct), that value will be shared among all the instances (or values).

有一些关于如何在 Swift 中为静态常量和静态变量编写代码的帖子。但不清楚何时使用静态常量和静态变量而不是常量和变量。有人可以解释一下吗?当您将静态 var/let 定义到类(或结构)中时,该值将在所有实例(或值)之间共享。

static variables/class are variables can be accessed without need of creation of any instance/object.

静态变量/类是无需创建任何实例/对象即可访问的变量。

class Human {
    static let numberOfEyes = 2 //human have only 2 eyes
    static var eyeDefect = false //whether human have side-effect or not. he can have defect later so its variable

    //other variables and functions
}

//you can access numberOfEyes like below no object of Human is created
print(Human.numberOfEyes)
print(Human.eyeDefect)

//Object of Human
let john = Human()

I think you know difference between constant and variable. In short, constant is that whose value never changes; numberOfEyes in above example and variable is that whose value changes; eyeDefect in above example.

我想你知道常量和变量之间的区别。简而言之,常量是其值永远不会改变的;上面例子中的 numberOfEyes 和变量是其值改变的;上例中的 eyeDefect。

static constant or variables are placed in memory(RAM) separate then the Objects. i.e. numberOfEyes have different memory space allocated than John object, its not inside John.

静态常量或变量放置在与对象分开的内存(RAM)中。即 numberOfEyes 分配的内存空间与 John 对象不同,它不在 John 内部。

now, when to use static constants/variables:

现在,何时使用静态常量/变量:

  1. When you use singleton design pattern: static let sharedInstance = APIManager()

    class APIManager(){
        static let sharedInstance = APIManager()
        //Your other variables/functions here below
    }
    //Use it as to get singleton instance of APIManager from anywhere in your application
    let instanceOfAPIManager = APIManager.sharedInstance
    
  2. When you need value of anything that is globally the same without need to make instance of the class under which it is defined like numberOfEyes in human class.

  3. Use of static variables/constants are not much recommended because of memory issues because once it's instantiated/assigned, it remains in memory until your application gets removed from the memory. I have found till now the best place to use static variables/constants is only while making singleton pattern and sometimes pointers for other normal variables and constants don't use static because: memory issue, it will be difficult to run unit testing in your code with static variables/constants. Not recommended to use as like in Human class also. instead use them as just constant or variables and access them by making instance.

    class Human {
     let numberOfEyes = 2 //human have only 2 eyes
     var eyeDefect = false //whether human have side-effect or not. he can have defect later so its variable
    
       //other variables and functions
     }
    
    //you can access numberOfEyes like below if you need just those values.
    print(Human().numberOfEyes)
    print(Human().eyeDefect)
    
  1. 当您使用单例设计模式时: static let sharedInstance = APIManager()

    class APIManager(){
        static let sharedInstance = APIManager()
        //Your other variables/functions here below
    }
    //Use it as to get singleton instance of APIManager from anywhere in your application
    let instanceOfAPIManager = APIManager.sharedInstance
    
  2. 当您需要任何全局相同的值时,无需创建在其下定义的类的实例,例如人类类中的 numberOfEyes。

  3. 由于内存问题,不推荐使用静态变量/常量,因为一旦它被实例化/分配,它就会保留在内存中,直到您的应用程序从内存中删除。到目前为止,我发现使用静态变量/常量的最佳位置只是在制作单例模式时,有时其他普通变量和常量的指针不使用静态,因为:内存问题,很难在代码中运行单元测试带有静态变量/常量。也不建议在 Human 类中使用。而是将它们用作常量或变量,并通过创建实例来访问它们。

    class Human {
     let numberOfEyes = 2 //human have only 2 eyes
     var eyeDefect = false //whether human have side-effect or not. he can have defect later so its variable
    
       //other variables and functions
     }
    
    //you can access numberOfEyes like below if you need just those values.
    print(Human().numberOfEyes)
    print(Human().eyeDefect)
    

回答by Julia Will

Static constants and variables do belong to the class itself, not to a particular instance. A class can also have static methods that can be called without creating an instance of a class.

静态常量和变量确实属于类本身,而不属于特定实例。类也可以有静态方法,无需创建类的实例即可调用这些方法。

So when you have a class MyClasswith a static var x, you can also access it through MyClass.xdirectly. xwill be shared among all instances of a class

所以当你有一个MyClass带有静态 var的类时x,你也可以MyClass.x直接访问它。x将在一个类的所有实例之间共享

回答by Honey

This is more of an important comment:

这是一个更重要的评论:

class Person {
    static var name = "Static John" // a property of Person 'type'
    var name = "Alex" // a property of Person 'instance'

    var nonStaticName = "Peter"
    static var staticName = "Sara"



    static func statFunc() {
        let x = Person.name // Static John
        let y = name // Static John or Alex?!  Static John!!!!
        let r = staticName // Sara
        let k = nonStaticName // ERROR: instance member 'nonStaticName' cannot be used on type 'Person'
        // The compiler is like: I'm referring to the `nonStaticName` property of which instance?! There is no instance! Sorry can't do!

    }

    func nonStaticFunc() {
        let x = Person.name // Static John
        let y = name // Static John or Alex?! Alex!!! Because we're in a instance scope...
        let k = nonStaticName // Obviously works
        let r = staticName // ERROR: static member 'staticName' cannot be used on instance of type 'Person'. Person.staticName will work
    }
}

Interesting observations:

有趣的观察:

First:

第一的:

static var name = "Static John" // a property of Person 'type'
var name = "Alex" // a property of Person 'instance'

creates no conflicts.

不会产生冲突。

Second:

第二:

You can't ever use instance variables inside static variables. You can use static variables inside instance functionsifyou refer to it by prefixing it with the type ie do Person.name, whereas

您永远不能在静态变量中使用实例变量。如果通过使用类型 ie do 前缀来引用它,可以在实例函数中使用静态变量,而Person.name

static variables can be accessed inside staticfunctions with or without prefixing the type ie Person.staticNameor staticNameboth work.

静态变量可以在静态函数中访问,可以使用或不使用类型前缀,即Person.staticNamestaticName两者都工作。