티스토리 뷰

Tech/Swift

스위프트 lazy 프로퍼티

Ellie Kim 2020. 3. 31. 15:24

lazy프로퍼티는 직접 사용할 때까지 계산되지 않습니다.

 

sean allen님의 예제가 잘 표현되어 있어서 참고했습니다.

 

잘 표현된 예제 한번 보시죠.

Player구조체가 있으며 name, team, position프로퍼티가 있고 lazy프로퍼티로 introduction이 있습니다.

struct Player {
    var name: String
    var team: String
    var position: String
    
    lazy var introduction = {
        return "Now entering the game: \(name), \(position) for the \(team)"
    }()
}

var jordan = Player(name: "Michael Jordan", team: "Bulls", position: "Shooting Guard")

print(jordan.introduction)

introduction을 lazy프로퍼티로 둔 이유는 반환되는 문자열 속에 사용되는 name, position, team 각 프로퍼티 값이 생성된 이후에 사용되기 때문입니다. 

 

name, team, position이 있어야 introduction을 사용할 수 있겠죠?

소개를 하려고 하는데 이름 팀 포지션도 모르면서 소개할 수 없잖아요!

 

그래서 lazy를 붙여줘 실제로 사용할 때 참조되도록 합니다.

 

또 다른 예를 봅시다.

Calculator이라는 구조체가 있고

구조체 내부에는 static함수가 있습니다.

이는 얼마나 게임을 했는지 반환해주는 함수입니다.

(극단적인 예를 들기위해서 1에서 4000번 루프를 돌고 4000을 리턴해줍니다)

struct Calculator {
    static func calculateGamesPlayed() -> Int {
        var games: [Int] = []
        for i in 1...4_000 { games.append(i) }
        return games.last!
    }
}

struct Player {
    var name: String
    var team: String
    var position: String
    var gamePlayed = Calculator.calculateGamesPlayed()
    
    lazy var introduction = {
        return "Now entering the game: \(name), \(position) for the \(team)"
    }()
}

var jordan = Player(name: "Michael Jordan", team: "Bulls", position: "Shooting Guard")

print(jordan.introduction)

여기서 lazy 프로퍼티를 사용하지 않는다면,

초기화 할때마다 4000번의 루프를 돌고 선수가 얼마나 플레이했는지 계산하게 됩니다. 

초기화할 때 바로 사용하지도 않는데 굉장히 비효율적입니다.

 

이를 해결하기 위해서 gamePlayed를 lazy프로퍼티로 만들어줍니다.

struct Calculator {
    static func calculateGamesPlayed() -> Int {
        var games: [Int] = []
        for i in 1...4_000 { games.append(i) }
        return games.last!
    }
}

struct Player {
    var name: String
    var team: String
    var position: String
    
    lazy var gamePlayed = {
        Calculator.calculateGamesPlayed()
    }()
    
    lazy var introduction = {
        return "Now entering the game: \(name), \(position) for the \(team)"
    }()
}

var jordan = Player(name: "Michael Jordan", team: "Bulls", position: "Shooting Guard")

print(jordan.introduction)
print(jordan.gamePlayed)

이렇게요.

 

그럼 실제로 gamePlayed를 사용하기 전까지는 4000번의 루프를 돌지 않고 

gamePlayed를 사용할 때 비로소 4000번의 루프가 돌게 됩니다.

 

+

참고로 여러 스레드에서 동시에 접근되고 프로퍼티가 아직 초기화되지 않은 경우

프로퍼티가 한 번만 초기화된다는 보장은 없습니다.

If a property marked with the lazy modifier is accessed by multiple threads simultaneously and the property has not yet been initialized, there is no guarantee that the property will be initialized only once.

 

resource:

https://www.youtube.com/watch?v=xKoua1Mi6qE

https://docs.swift.org/swift-book/LanguageGuide/Properties.html

'Tech > Swift' 카테고리의 다른 글

스위프트 인터뷰  (0) 2020.05.30
스위프트5.0 Result타입  (0) 2020.04.01
스위프트 typealias에 대해서  (0) 2020.03.31
Swift 5.2 Key Path Exressions as Functions  (0) 2020.03.04
문자열 결합  (0) 2020.01.05
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함