スイフトのプロパティ


Swift プロパティは、値を特定のクラス、構造、または列挙に関連付けます。

プロパティは、格納されたプロパティと計算されたプロパティに分類できます:

格納されたプロパティ 計算されたプロパティ
インスタンスの一部として定数または変数を格納 Compute (格納ではなく) ) value
クラスと構造体の場合クラス、構造体、列挙型の場合

保存されたプロパティと計算されたプロパティは通常、特定のタイプのインスタンスで使用されます。

属性は型自体に直接使用することもできます。そのような属性は型属性と呼ばれます。

さらに、属性値の変更を監視してカスタム操作をトリガーする属性オブザーバーを定義することもできます。プロパティ オブザーバーは、自分で作成した保存されたプロパティ、または親クラスから継承したプロパティに追加できます。


ストアド プロパティ

簡単に言えば、ストアド プロパティは、特定のクラスまたは構造体のインスタンスに保存される定数または変数です。

ストアド属性は、変数ストアド属性 (キーワード var で定義) または定数ストアド属性 (キーワード let で定義) にすることができます。

  • 保存された属性を定義するときにデフォルト値を指定できます

  • 構築プロセス中に保存された属性の値を設定または変更したり、定数の保存された属性の値を変更したりすることもできます

import Cocoa

struct Number
{
   var digits: Int
   let pi = 3.1415
}

var n = Number(digits: 12345)
n.digits = 67

print("\(n.digits)")
print("\(n.pi)")

上記のプログラム実行の出力結果は次のとおりです: :

67
3.1415

次のコードを考えてみましょう:

let pi = 3.1415

このコードでは、格納されたプロパティを定義するときに pi にデフォルト値 (pi = 3.1415) が割り当てられるため、いつインスタンス化しても関係ありません。構造体は変わりません。

定数ストレージ属性を定義した場合、それを変更しようとすると、以下に示すようにエラーが報告されます:

import Cocoa

struct Number
{
    var digits: Int
    let numbers = 3.1415
}

var n = Number(digits: 12345)
n.digits = 67

print("\(n.digits)")
print("\(n.numbers)")
n.numbers = 8.7

上記のプログラムは実行時にエラーを報告します。エラーは次のとおりです:

error: cannot assign to property: 'numbers' is a 'let' constant
n.numbers = 8.7

It 'numbers' は定数であり、変更できないことを意味します。


遅延ストレージ プロパティ

遅延ストレージ プロパティとは、最初に呼び出されたときにのみ初期値が計算されるプロパティを指します。

遅延ストレージ プロパティを示すには、プロパティ宣言の前に lazy を使用します。

注:
遅延ストレージ プロパティは、インスタンスの構築が完了するまでプロパティの値を使用できない可能性があるため、(var キーワードを使用して) 変数として宣言する必要があります。定数プロパティは構築プロセスが完了する前に初期値を持つ必要があるため、遅延プロパティとして宣言することはできません。

遅延ストレージ プロパティは通常、次の目的で使用されます:

  • オブジェクトの作成を遅延します。

  • 属性の値が他の未知のクラスに依存する場合

import Cocoa

class sample {
    lazy var no = number() // `var` 关键字是必须的
}

class number {
    var name = "php Swift 教程"
}

var firstsample = sample()
print(firstsample.no.name)

上記のプログラム実行の出力結果は次のとおりです:

php Swift 教程

インスタンス化された変数

Objective-C の経験がある場合は、知っておく必要がありますObjective-C はクラス インスタンスのストレージ値と参照で 2 つのメソッドを提供します。プロパティの場合、インスタンス変数をプロパティ値のバックエンド ストレージとして使用することもできます。

Swift プログラミング言語では、これらの理論は属性を使用して統合され、実装されます。 Swift のプロパティには対応するインスタンス変数がなく、プロパティのバックエンド ストレージに直接アクセスすることはできません。これにより、さまざまなシナリオでのアクセス方法の問題が回避され、属性の定義が 1 つのステートメントに簡素化されます。

名前、型、メモリ管理特性を含む、型のプロパティに関するすべての情報は、単一の場所 (型定義内) で定義されます。


計算されたプロパティ

保存されたプロパティに加えて、クラス、構造体、および列挙は 計算されたプロパティ を定義できます。計算されたプロパティは値を直接格納しませんが、値を取得するためのゲッターと、他の値を間接的に設定するためのオプションのセッターを提供します。プロパティまたは変数の値。

import Cocoa

class sample {
    var no1 = 0.0, no2 = 0.0
    var length = 300.0, breadth = 150.0
    
    var middle: (Double, Double) {
        get{
            return (length / 2, breadth / 2)
        }
        set(axis){
            no1 = axis.0 - (length / 2)
            no2 = axis.1 - (breadth / 2)
        }
    }
}

var result = sample()
print(result.middle)
result.middle = (0.0, 10.0)

print(result.no1)
print(result.no2)

上記のプログラムの実行出力は次のとおりです:

(150.0, 75.0)
-150.0
-65.0

計算されたプロパティのセッターが新しい値を表すパラメーター名を定義していない場合は、デフォルト名 newValue を使用できます。


読み取り専用の計算プロパティ

ゲッターのみを持ちセッターを持たない計算プロパティは、読み取り専用の計算プロパティです。

読み取り専用の計算プロパティは常に値を返し、ドット (.) 演算子を介してアクセスできますが、新しい値を設定することはできません。

import Cocoa

class film {
    var head = ""
    var duration = 0.0
    var metaInfo: [String:String] {
        return [
            "head": self.head,
            "duration":"\(self.duration)"
        ]
    }
}

var movie = film()
movie.head = "Swift 属性"
movie.duration = 3.09

print(movie.metaInfo["head"]!)
print(movie.metaInfo["duration"]!)

上記のプログラムの実行出力は次のとおりです:

Swift 属性
3.09

注:

読み取り専用の計算プロパティを含む計算プロパティを定義するには、var キーワードを使用する必要があります。固定されていません。 let キーワードは、初期化後に変更できない値を示す定数属性を宣言するためにのみ使用されます。 var关键字定义计算属性,包括只读计算属性,因为它们的值不是固定的。let关键字只用来声明常量属性,表示初始化后再也无法修改的值。


属性观察器

属性观察器监控和响应属性值的变化,每次属性被设置值的时候都会调用属性观察器,甚至新的值和现在的值相同的时候也不例外。

可以为除了延迟存储属性之外的其他存储属性添加属性观察器,也可以通过重载属性的方式为继承的属性(包括存储属性和计算属性)添加属性观察器。

注意:
不需要为无法重载的计算属性添加属性观察器,因为可以通过 setter 直接监控和响应值的变化。

可以为属性添加如下的一个或全部观察器:

  • willSet在设置新的值之前调用

  • didSet

  • プロパティ オブザーバー
  • プロパティ オブザーバーは、新しい値が現在の値と同じである場合でも、プロパティ値の変更を監視し、応答します。

  • 遅延ストアド プロパティを除く他のストアド プロパティのプロパティ オブザーバーを追加できます。また、プロパティをオーバーロードすることで、継承されたプロパティ (ストアド プロパティと計算プロパティを含む) のプロパティ オブザーバーを追加することもできます。

注:
値の変更は直接監視でき、セッターを通じて応答できるため、オーバーロードできない計算プロパティにプロパティ オブザーバーを追加する必要はありません。

次のオブザーバーの 1 つまたはすべてをプロパティに追加できます:

    willSet は、新しい値を設定する前に呼び出されます。
    import Cocoa
    
    class Samplepgm {
        var counter: Int = 0{
            willSet(newTotal){
                print("计数器: \(newTotal)")
            }
            didSet{
                if counter > oldValue {
                    print("新增数 \(counter - oldValue)")
                }
            }
        }
    }
    let NewCounter = Samplepgm()
    NewCounter.counter = 100
    NewCounter.counter = 800
    上記プログラムの出力結果実行は次のとおりです:
    计数器: 100
    新增数 100
    计数器: 800
    新增数 700
    グローバル変数とローカル変数計算されたプロパティとプロパティ オブザーバー 説明されているパターンは、グローバル変数とローカル変数にも使用できます。 ローカル変数グローバル変数
    didSetは、新しい値が設定された直後に呼び出されますwillSetおよびdidSetオブザーバーは、プロパティの初期化プロセス中に呼び出されません
    関数、メソッド、またはクロージャー内で定義された変数。 型の外部で定義された関数、メソッド、クロージャ、または変数。
    は、値の保存と取得に使用されます。 🎜🎜値の保存と取得用。 🎜🎜🎜🎜保存されたプロパティは、値の取得と設定に使用されます。 🎜🎜保存されたプロパティは、値の取得と設定に使用されます。 🎜🎜🎜🎜 は計算されたプロパティにも使用されます。 🎜🎜計算されたプロパティにも使用されます。 🎜🎜🎜🎜

    型属性

    型属性は、型定義の一部として、型の最も外側の中括弧 ({}) 内に記述されます。

    値の型の型属性を定義するにはキーワード static を使用し、クラスの型属性を定義するにはキーワード class を使用します。

    struct Structname {
       static var storedTypeProperty = " "
       static var computedTypeProperty: Int {
          // 这里返回一个 Int 值
       }
    }
    
    enum Enumname {
       static var storedTypeProperty = " "
       static var computedTypeProperty: Int {
          // 这里返回一个 Int 值
       }
    }
    
    class Classname {
       class var computedTypeProperty: Int {
          // 这里返回一个 Int 值
       }
    }

    注:
    この例の計算型プロパティは読み取り専用ですが、インスタンスの計算型プロパティの構文と同様に、読み取りおよび書き込み可能な計算型プロパティを定義することもできます。


    型属性の値の取得と設定

    インスタンス属性と同様に、型属性にもドット演算子 (.) を使用してアクセスします。ただし、型プロパティは、インスタンスを通じてではなく、型自体を通じて取得および設定されます。例は次のとおりです。

    import Cocoa
    
    struct StudMarks {
       static let markCount = 97
       static var totalCount = 0
       var InternalMarks: Int = 0 {
          didSet {
             if InternalMarks > StudMarks.markCount {
                InternalMarks = StudMarks.markCount
             }
             if InternalMarks > StudMarks.totalCount {
                StudMarks.totalCount = InternalMarks
             }
          }
       }
    }
    
    var stud1Mark1 = StudMarks()
    var stud1Mark2 = StudMarks()
    
    stud1Mark1.InternalMarks = 98
    print(stud1Mark1.InternalMarks) 
    
    stud1Mark2.InternalMarks = 87
    print(stud1Mark2.InternalMarks)

    上記プログラムの実行の出力結果は次のとおりです。

    97
    87