develop

Struct Mutating 본문

iOS

Struct Mutating

pikachu987 2021. 1. 30. 20:37
반응형

struct나 protocol 확장 에서 self 변수를 참조해 수정하려면 mutating을 써야 한다.

protocol ExampleProtocol {
    var value: Int? { set get }
}

extension ExampleProtocol {
    mutating func exampleFunc() {
        self.value = 5
    }
}

struct Example1 {
    var value: Int?
    
    mutating func exampleFunc() {
        self.value = 5
    }
}

struct에서 변수의 값이 변경되면 struct 전체가 복사되고 주소값이 변경이 된다.

값이 변경될 때 struct가 복사되는 이유는 swift가 함수형 언어이고 불변성이 중요한 요소라서 전체가 복사가 되고 주소값이 변경이 된다. 그러면 다중 쓰레드에서 세이프하게 작동할 수 있게 된다.

주소값을 보려면 withUnsafePointer 를 사용하면 된다.
struct Example {
    var value: Int?
    static var value1: Int?
    
    mutating func updateValue(_ value: Int?) {
        self.value = value
    }
    
    static func updateValue1(_ value1: Int?) {
        self.value1 = value1
    }
}

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        var example = Example()
        withUnsafePointer(to: example) {
            print($0)
        }
        example.value = 5
        withUnsafePointer(to: example) {
            print($0)
        }
        example.updateValue(5)
        withUnsafePointer(to: example) {
            print($0)
        }
        Example.value1 = 5
        withUnsafePointer(to: example) {
            print($0)
        }
        Example.updateValue1(5)
        withUnsafePointer(to: example) {
            print($0)
        }
    }

}
0x00007ffee440f108
0x00007ffee440f0f0
0x00007ffee440f0e0
0x00007ffee440f0b8
0x00007ffee440f0a8

특이한 점은 static 변수값을 수정해도 example의 주소값이 변경된다는 점이다.

 

플레이그라운드에서는 struct의 변수 값을 수정해도 주소값이 변경되지 않고 동일하게 나온다.

 

var example = Example() {
    didSet {
        print(example)
    }
}
withUnsafePointer(to: example) {
    print($0)
}
example.value = 5
withUnsafePointer(to: example) {
    print($0)
}
example.updateValue(5)
withUnsafePointer(to: example) {
    print($0)
}
Example.value1 = 5
withUnsafePointer(to: example) {
    print($0)
}
Example.updateValue1(5)
withUnsafePointer(to: example) {
    print($0)
}
0x00007ffeecb18118
Example(value: Optional(5))
0x00007ffeecb180e8
Example(value: Optional(5))
0x00007ffeecb18098
0x00007ffeecb18058
0x00007ffeecb18030

struct에서 멤버변수를 변경하면 didSet이 호출이 된다.

하지만 static변수를 변경하면 주소값은 변하지만 didSet 호출은 되지 않는다.

반응형

'iOS' 카테고리의 다른 글

KVC KVO (Key-Value Coding, Key-Value Observing)  (0) 2021.01.31
Reference Equal 참조 비교하기  (0) 2021.01.31
Require  (0) 2021.01.29
Class convenience init  (0) 2021.01.28
Class Struct == Operator  (0) 2021.01.27
Comments