[swift] 13. 객체 생성자, 해제자

몽이 누나·2022년 4월 24일
0

swift 기초 문법

목록 보기
13/17
post-thumbnail

📖 객체 생성자와 해제자

📌 객체 생성자 (Initialization)

객체 생성자 는 처음에 클래스가 객체화 될 때 (빵틀에 의해 빵이 구워질 때), 자동으로 실행됩니다.
swift에서는 init 이라는 키워드의 메소드가 이를 담당하며, 초기화 작업을 담당합니다.

💬 객체가 생성되면, 그 객체는 메모리에 올라가게 됩니다.

📌 객체 해제자 (Deinitialization)

객체 해제자 는 init의 반대 요소로, 클래스 인스턴스가 더 이상 필요 없어져 메모리에서 사라질 때 호출되는 기능입니다. deinit 이라는 키워드의 메소드가 담당합니다.

🤔 레퍼런스 카운트가 0이 될 때 호출?


ex)

class MyFriend {
    var name : String
    
    init(_ name : String = "이름 없음") {
        self.name = name
        print("My friend 가 메모리에 올라갔다. name : \(self.name)")
    }
    
    deinit{
        print("메모리에서 사라짐 - ", self.name)
    }
}

💬 객체를 생성하고, 메모리 주소를 확인해봅시다.

// Unmanaged.passUnretainde(객체).to0paque()
// 로 해당 객체의 메모리 주소를 프린트 할 수 있습니다.

let anObjectMemoryAddress = Unmanaged.passRetained(aFriend).toOpaque()
let secondMemoryAddress = Unmanaged.passRetained(myFriend).toOpaque()

print(anObjectMemoryAddress)
print(secondMemoryAddress)
// 주소가 생기게 됨

>>> My friend 가 메모리에 올라갔다.
My friend 가 메모리에 올라갔다.
0x0000600003b6cfa0
0x0000600003b4ab40

🤔 deinit을 검증하기 위한 코드를 추가로 작성해봅시다.

class MyFriend {
    var name : String
    
    init(_ name : String = "이름 없음") {
        self.name = name
        print("My friend 가 메모리에 올라갔다.")
    }
    
    deinit{
        print("메모리에서 사라짐 - ", self.name)
    }
    
    // class 안에 추가로 작성
    var calledTimes = 0 // 불려진 횟수
    let MAX_TIMES = 5 // 최대 횟수
    static var instanceOfSelf = [MyFriend]()
    
    class func destroySelf(object:MyFriend) {
        instanceOfSelf = instanceOfSelf.filter { (aFriend : MyFriend) in
            aFriend !== object
        }
    } // 같지 않은 애들만 넣는다??
    
    // 정해진 횟수를 넘으면 폭발!
    
    func call() {
        calledTimes += 1
        print("called \(calledTimes)")
        if calledTimes > MAX_TIMES {
            MyFriend.destroySelf(object: self)
        }
    }
    
}

let myFriend = MyFriend("몽이 누나")
let aFriend = MyFriend("몽이 아빠")

// Unmanaged.passUnretainde(객체).to0paque()
// 로 해당 객체의 메모리 주소를 프린트 할 수 있습니다.

let anObjectMemoryAddress = Unmanaged.passRetained(aFriend).toOpaque()
let secondMemoryAddress = Unmanaged.passRetained(myFriend).toOpaque()

print(anObjectMemoryAddress)
print(secondMemoryAddress)
// 주소가 생기게 됨

weak var aFriendTobeDestoried = MyFriend("개발하는 몽이 누나")

if aFriendTobeDestoried != nil {
    aFriendTobeDestoried!.call()
} else {
    print("객체가 더 이상 메모리에 없습니다.")
}

>>> My friend 가 메모리에 올라갔다.
My friend 가 메모리에 올라갔다.
0x0000600003eaaf70
0x0000600003ebc000
My friend 가 메모리에 올라갔다.
메모리에서 사라짐 -  개발하는 몽이 누나
객체가 더 이상 메모리에 없습니다.

참고 자료

profile
몽이 누나의 코딩 일기

0개의 댓글