10-2. Propertyオブザーバ
14186 ワード
Propertyオブザーバーは、Property値が変更されたかどうかを観察し、応答します.現在の値が新しい値に等しくても、値の設定時に呼び出されます.以下の場合、オブザーバを追加できます.定義された格納されたProperty 保存されたProperty を継承計算のプロパティ を継承
職業観察者定義には、willsetとdidsetの2つの選択がある. willsetは、値が保存される前に呼び出されます.定数パラメータは、新しいproperty値を渡します.willSet実装の一部として、このパラメータに新しい名前を付けることができます.パラメータ名と実装時に括弧を記入しない場合は、newValueの基本パラメータ として作成されます. didSetは、値が保存されると呼び出される.以前のproperty値を含む定数パラメータを渡します.パラメータ名またはoldValueをデフォルトパラメータとして使用できます.didSetオブザーバproperty値が割り当てられている場合は、先ほど設定した値の代わりに新しい値が使用されます. スーパークラスpropertyのwill,didSetオブザーバーはスーパークラス初期化呼び出し後,サブクラスにpropertyを設定したときに呼び出す.スーパークラス初期化が呼び出されるまで、クラス自体のpropertyを設定しても呼び出されません. オブザーバを有するPropertyが入出力パラメータとして関数に渡されると、オブザーバは常に呼び出される.すなわち,関数に変化する変数の状態をリアルタイムで理解し,観察機能を実現できる. プロトコルは、プロトコル格納方式を管理するコードと、プロトコルを定義するコードとの間に分離層を追加する.wrappedValue propertyを定義する構造体、列挙型、またはクラスを作成し、property Rapperを定義します. パッケージのPropertyの初期値を設定するには、設定する前にProperty Rapperを直接初期化する必要があります. properの初期化タイプによって、初期化方式が異なります.次回確認できます.
職業観察者
class StepCounter {
var totalStep : Int = 0 {
willSet(newTotalSteps) {
print("\(newTotalSteps)")
} didSet {
if totalSteps > oldValue {
print("\(totalSteps - oldValue)")
}
}
}
}
let stepCounter = StepCounter()
stepCounter.totalSteps = 200
//윌셋에서 200 출력, 디드셋에서 200(200-0)출력한다.
stepCounter.totalSteps = 360
//윌셋에서 360, 디드셋에서 160(360-200)을 출력한다.
//바뀌기 직전과 직후를 출력하므로 둘다 출력이 되고, 꼭 둘다 쌍으로 선언할 필요는 없다.
//oldValue를 통해서 디드셋에서 바뀌기 전 값 접근이 가능하다는게 포인트다.
専門家
@propertyWrapper
struct TwelveOrLess {
private var number = 0
var wrappedValue : Int {
get {
return number
}
set {
number = min(newValue, 12)
}
}
//게터는 저장된 값을 반환하고, 세터는 새로운 값이 12보다 작거나 같은걸 확인하고 반환한다.
//프로퍼티 래퍼는 wrappedValue를 프로퍼티의 값으로 반환해주게 된다.
次の例では、Property Rapperを使用します.プロフェッショナルRapperはプロフェッショナルに一定の特性を与えるキーワードです. struct SmallRectangle {
@TwelveOrLess var height : Int
@TwelveOrLess var width : Int
}
var rectangle = SmallRectangle()
print(rectangle.height)
//0을 출력한다.
rectangle.height = 10
//새로운 값을 넣어줬으니 setter가 작용할 것이다.
print(rectangle.height)
//아직 12보다 작으므로 10을 출력한다.
rectangle.height = 24
//세터가 작용하고 12보다 크므로 12를 출력한다.
@propertyWrapper
struct SmallNumber {
private var maximum : Int
private var number : Int
var wrappedValue : Int {
get { return number }
set { number = min(newValue, maximun) }
//여기에서 보면 현재 구조체 내 프로퍼티에 값이 하나도 정의되지 않은 상태이다.
init() {
maximum = 12
number = 0
init(wrappedValue : Int) {
maximun = 12
number = min(wrappedValue, maximun)
}
init(wrappedValue : Int, maximum : Int) {
self.maximum = maximum
number = min(wrappedValue, maximun)
}
//기본적으로 3개의 초기화를 지원한다.
struct ZeroRectangle {
@SmallNumber var height : Int
@SmallNumber var width : Int
}
var zeroRectangle = ZeroRectangle()
print(zeroRectangle.height, zeroRectangle.width)
//0, 0을 출력한다. 가장 첫 init() 이 호출되기 때문이다.
struct UnitRectangle {
@SmallNumber var height : Int = 1
@SmallNumber var width : Int = 1
}
var unitRectangle = UnitRectngle()
print(unitRectangle.height, unitRectangle.width)
//1, 1을 출력한다. 초기값을 설정해줘도 init()을 호출한다.
//초기값으로 wrappedValue를 전달하지 않았기에 그렇다.
struct NarrowRectangle {
@SmallNumber(wrappedValue : 2, maximun : 5) var height : Int
@SmallNumber(wrappedValue : 3, maximun : 4) var width : Int
}
var narrowRectangle = NarrowRectangle()
print(narrowRectangle.height, narrowRectangle.width)
//2, 3을 출력한다. 다음에서는 래핑한 값을 통해서 초기화가 가능하다.
//위의 예시에서 3번에 해당하는 초기화를 사용하게 된다.
//init(wrappedValue : Int, maximun : Int)
Reference
この問題について(10-2. Propertyオブザーバ), 我々は、より多くの情報をここで見つけました https://velog.io/@devleeky16498/10-2.-프로퍼티-관찰자property-observer-프로퍼티-래퍼テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol