web-dev-qa-db-ja.com

Swiftで静的定数と静的変数を使用する場合

Swiftでstatic constantおよびstatic variableのコードを記述する方法に関する投稿があります。しかし、constantvariableではなく、static constantstatic variableをいつ使用するかは明確ではありません。誰か説明できますか?

31
Mike

静的なvar/letをクラス(または構造体)に定義すると、その情報はすべてのインスタンス(または値)で共有されます。

情報を共有する

class Animal {
    static var nums = 0

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

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

ご覧のとおり、Animalの2つの個別のインスタンスを作成しましたが、どちらも同じ静的変数numsを共有しています。

シングルトン

多くの場合、静的定数はシングルトンパターンを採用するために使用されます。この場合、クラスのインスタンスを1つしか割り当てないようにします。そのためには、共有インスタンスへの参照を定数内に保存し、初期化子を非表示にします。

class Singleton {
    static let sharedInstance = Singleton()

    private init() { }

    func doSomething() { }
}

Singletonインスタンスが必要になったら、

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

このアプローチにより、アプリの異なるポイントであっても、常に同じインスタンスを使用できます。

78
Luca Angeletti

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)
    
11
Dari

静的定数と変数は、特定のインスタンスではなく、クラス自体に属します。クラスには、クラスのインスタンスを作成せずに呼び出すことができる静的メソッドを含めることもできます。

したがって、静的変数MyClassを持つクラスxがある場合、MyClass.xから直接アクセスすることもできます。 xは、クラスのすべてのインスタンス間で共有されます

4
Julia Will

これはより重要なコメントです。

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 referrting 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'

競合は発生しません。

2番目:

静的変数内でインスタンス変数を使用することはできません。 インスタンス関数if内で静的変数を使用できます。つまり、do Person.nameという型をプレフィックスとして使用して参照します。

静的変数にアクセスできます内部静的型の前またはなしの関数、つまりPerson.staticNameまたはstaticNameの両方が機能します。

0
Honey