automatic reference counting - swift
DESCRIPTION
Automatic Reference Counting - SwiftTRANSCRIPT
Automatic Reference Counting
Swift
순서
1. ARC 란 ?2. 메모리 해제 예제3. 강한 참조4. 강한 참조 순환5. 약한 (weak) 참조6. 미소유 (unowned) 참조7. 암시적으로 드러난 옵셔널 속성8. 클로저를 위한 강한 참조 순환9. 클로저의 강한 참조 순환 해결
ARC 란 ?
ARC 는 프로그램 내에서 클래스 인스턴스가 더 이상 필요하지 않을 때 자동으로 메모리를 해제합니다 .
구조체와 열거형은 Value Type 이라 해당사항이 없습니다 .
메모리 해제 예제
var reference1: Person?var reference2: Person?var reference3: Person?reference1 = Person(name: "John")reference2 = reference1reference3 = reference1reference1 = nilreference2 = nilreference3 = nil // 참조 카운트가 0 이 되면 해제
강한 참조var john: Person?var number73: Apartment?john = Person(name: "John Appleseed")number73 = Apartment(number: 73)
john = nilnumber73 = nil// 참조 카운트가 0 이 되면 메모리에서 해제된다
강한 참조 순환john!.apartment = number73number73!.tenant = john
john = nilnumber73 = nil// 둘 다 메모리 해제되지 않는다
강한 참조 순환 #2john = nilnumber73 = nil// 위 코드의 결과로 메모리 누수가 일어난다
서로 안놔주고 붙어 있는 꼴
약한 참조weak var tenant: Person?// weak 를 앞에 써주어 약한 참조 , 옵셔널 사용
약한 참조 #2john = nil// 강한 참조가 없어졌으므로 메모리 해제된다
약한 참조 #3number73 = nil// 역시 메모리에서 해제된다
미소유 참조unowned let customer: Customer// unowned 키워드를 사용 , 옵셔널 변수가 아니므로 항상 값이 있다는 전제로// 사용되는 점이 약한 참조와는 다른 점이다
var john: Customer?john = Customer(name: "John Appleseed")john!.card = CreditCard(number: 1234_5678_9012_3456, customer: john!)
미소유 참조 #2john = nil// john 과 john.card 에 할당된 CreditCard 인스턴스도 함께 해제된다
암시적으로 드러난 옵셔널 속성let capitalCity: City!// 암시적으로 드러난 옵셔널로 선언하면 !(unwrap) 할 필요없이 사용
var country = Country(name: "Canada", capitalName: "Ottawa")println("\(country.name)'s capital city is called \(country.capitalCity.name)")
let capitalCity: City?// 옵셔널로 capitalCity 를 선언했다면 !(unwrap) 해야 한다println("\(country.name)'s capital city is called \(country.capitalCity!.name)")
클로저를 위한 강한 참조 순환class HTMLElement { lazy var asHTML: () -> String = { if let text = self.text { return "<\(self.name)>\(text)</\(self.name)>" } else { return "<\(self.name) />" } }...
강한 참조 순환으로 메모리에서 해제되지 않는다
클로저의 강한 참조 순환 해결lazy var asHTML: () -> String = { [unowned self] in if let text = self.text { return "<\(self.name)>\(text)</\(self.name)>" } else { return "<\(self.name) />" }} // [unowned self, weak otherObject, ...] in 이런식으로 capture list 나열가능