【问题标题】:When to use static constant and variable in Swift?什么时候在 Swift 中使用静态常量和变量?
【发布时间】:2016-10-08 15:27:42
【问题描述】:

有一些帖子介绍了如何在 Swift 中为 static constantstatic variable 编写代码。但不清楚何时使用static constantstatic variable 而不是constantvariable。谁能解释一下?

【问题讨论】:

    标签: ios swift variables static constants


    【解决方案1】:

    这是更重要的评论:

    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
        }
    }
    

    有趣的观察:

    第一:

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

    不会产生冲突。

    第二:

    您永远不能在静态变量中使用实例变量。您可以在 instance functions if 中使用静态变量,通过在其前面加上类型即 do Person.name 来引用它,而

    静态变量可以在内部静态函数中访问,可以带或不带前缀类型,即Person.staticNamestaticName 都可以。

    【讨论】:

      【解决方案2】:

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

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

      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()
      

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

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

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

      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)
        

      【讨论】:

        【解决方案3】:

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

        分享信息

        class Animal {
            static var nums = 0
        
            init() {
                Animal.nums += 1
            }
        }
        
        let dog = Animal()
        Animal.nums // 1
        let cat = Animal()
        Animal.nums // 2
        

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

        单例

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

        class Singleton {
            static let sharedInstance = Singleton()
        
            private init() { }
        
            func doSomething() { }
        }
        

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

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

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

        【讨论】:

        • 谢谢。这解释得很清楚。您能否确认我的理解是否正确: 1. 正如一些文档所述,静态变量和常量在这里是类型,而不是实例; 2.可以像类的属性一样使用。
        • @Mike: 1) 静态 var/let 可以引用一个类的实例(如我的 Singleton 示例中)或可以存储一个值(如Animal 示例中)。就像普通的 var/let 一样。 2) 是的,我们可以看到 static var/let 类似于属于类本身而不属于实例的属性。
        • 谢谢。现在我完全明白如何使用静态了。
        • 1.类中的静态变量是类级别的,而不是对象级别的(我们不需要初始化类来访问变量)。 2。静态变量在类 3 的不同实例中具有相同的引用。静态变量对子类不可见。
        • 非常感谢。这让我很困惑很长时间。但现在它清楚了。
        【解决方案4】:

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

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

        【讨论】:

        • 谢谢,我明白了。祝你有美好的一天!
        猜你喜欢
        • 1970-01-01
        • 2023-03-22
        • 2010-11-18
        • 1970-01-01
        • 1970-01-01
        • 2021-04-15
        • 2012-02-01
        • 2015-10-14
        • 2011-01-14
        相关资源
        最近更新 更多