스위프트 속성


Swift 속성은 값을 특정 클래스, 구조 또는 열거형과 연결합니다.

속성은 저장 속성과 계산 속성으로 나눌 수 있습니다.

저장 속성 계산 속성
상수 또는 변수를 인스턴스의 일부로 저장 계산(저장 대신) 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 '숫자'가 상수라는 뜻이므로 수정할 수 없습니다.


Lazy 저장소 속성

Lazy 저장소 속성은 처음 호출될 때만 초기값이 계산되는 속성을 나타냅니다.

lazy 저장소 속성을 나타내려면 속성 선언 앞에 lazy를 사용하세요.

참고:
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는 클래스 인스턴스 저장 값과 참조가 두 가지 방법을 제공한다는 것입니다. 속성의 경우 인스턴스 변수를 속성 값의 백엔드 스토리지로 사용할 수도 있습니다.

Swift 프로그래밍 언어에서는 이러한 이론이 속성을 사용하여 통합되고 구현됩니다. Swift의 속성에는 해당 인스턴스 변수가 없으며 속성의 백엔드 저장소에 직접 액세스할 수 없습니다. 이는 다양한 시나리오에서 액세스 방법의 문제를 방지하고 속성 정의를 하나의 명령문으로 단순화합니다.

이름 지정, 유형 및 메모리 관리 특성을 포함하여 유형의 속성에 대한 모든 정보는 단일 위치(유형 정의)에서 정의됩니다.


계산된 속성

저장된 속성 외에도 클래스, 구조체 및 열거형은 계산된 속성을 정의할 수 있습니다. 계산된 속성은 값을 직접 저장하지 않지만 값을 얻기 위한 getter와 다른 값을 간접적으로 설정하기 위한 선택적 setter를 제공합니다. 속성 또는 변수의 값입니다.

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를 사용할 수 있습니다.


읽기 전용 계산 속성

getter만 있고 setter는 없는 계산 속성은 읽기 전용 계산 속성입니다.

읽기 전용 계산 속성은 항상 값을 반환하고 점(.) 연산자를 통해 액세스할 수 있지만 새 값을 설정할 수는 없습니다.

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

  • Property Observer
  • Property Observer는 속성 값의 변경 사항을 모니터링하고 응답합니다. 속성 관찰자는 새 값이 현재 예외와 동일한 경우에도 속성이 설정될 때마다 호출됩니다.

  • 지연 저장 속성을 제외한 다른 저장 속성에 대해 속성 관찰자를 추가할 수 있으며, 속성을 오버로드하여 상속된 속성(저장 속성 및 계산 속성 포함)에 대해 속성 관찰자를 추가할 수도 있습니다.

참고:
오버로드할 수 없는 계산된 속성에 대해서는 속성 관찰자를 추가할 필요가 없습니다. 값 변경을 직접 모니터링하고 setter를 통해 응답할 수 있기 때문입니다.

다음 관찰자 중 하나 또는 모두를 속성에 추가할 수 있습니다.

    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