Person
클래스 타입을 갖는 reference 변수 3개를 선언합니다. 이 변수는 모두 옵셔널 변수입니다. 그래서 초기값으로 모두 nil
을 갖고 있습니다.reference2
, reference3
모두 처음에 reference1
이 참조하고 있는 같은 Person
인스턴스를 참조하게 됩니다. 이 시점에 Person
인스턴스에 대한 참조 횟수는 3이 됩니다. 그리고 나서 reference1
, reference2
두 변수의 참조를 해지합니다. 그렇게 되면 Person
인스턴스에 대한 참조 횟수는 아직 1이어서 Person
인스턴스는 해지되지는 않습니다.Person
인스턴스를 참조하고있는 나머지 변수 reference3
의 참조를 해지하면 더이상 Person
인스턴스를 참조하고있는 것이 없으므로 ARC가 Person
인스턴스를 메모리에서 해지하게 됩니다.Person
인스턴스가 메모리에서 내려 갔음을 확인할 수 있습니다.Person
이라는 클래스는 변수로 Apartment
클래스의 인스턴스를 소유하고 있고 그 Apartment
클래스에서는 변수로 Person
형의 인스턴스를 소유하고 있습니다. 만약 다음과 같이 변수를 선언하고 인스턴스를 생성하면 어떤 일이 발생할까요? Person
과 Apartment
형의 변수를 각각 선언합니다.NOTE ARC에서 약한 참조에 nil을 할당하면 프로퍼티 옵저버는 실행되지 않습니다.
NOTE 가비지 콜렉션을 사용하는 시스템에서 weak pointer를 단순한 시스템 캐싱 목적으로 사용하기도 합니다. 왜냐하면 메모리가 소모가 많아지면 가비지 콜렉터를 실행해서 강한 참조가 없는 객체를 메모리에서 해제하는 식으로 동작하기 때문입니다. 하지만 ARC는 이 경우와 다르게 참조 횟수가 0이 되는 즉시 해당 인스턴스를 제거하기 때문에 약한 참조를 이런 목적으로 사용할 수 없습니다.
IMPORTANT 미소유 참조는 참조 대상 인스턴스가 항상 존재한다고 생각하기 때문에 만약 미소유 참조로 선언된 인스턴스가 해제됐는데 접근하게 되면 런타임 에러가 발생합니다.
CreditCard
인스턴스를 참조하고 있고 CreditCard는 customer로 Custome
인스턴스를 참조하고 있습니다. customer는 미소유 참조 unowned로 선언합니다. 이유는 고객과 신용카드를 비교해 봤을때 신용카드는 없더라도 사용자는 남아있을 것이기 때문입니다. 다시말하면 사용자는 항상 존재합니다. 그래서 CreditCard에 customer를 unowned로 선언합니다.NOTE CreditCard에서 카드 번호인 number는 충분히 긴 숫자를 저장할 수 있도록 하기 위해 Int가 아닌 UInt로 사용합니다. UInt64형은 32비트, 64비트 시스템 모두에서 16자리 숫자를 저장할 수 있습니다.
NOTE 위 예제는 안전하게 미소유 참조를 사용하는 방법의 예였습니다. 반면 Swift에서는 런타임에 안전성 확인을 하지 않고 사용하는 unsafe 미소유 참조도 제공합니다. 이것을 제공해 주는 이유는 성능 때문입니다.
() -> String
클로저를 사용합니다. 그리고 이 클로저 안에서 self.text와 self.name과 같이 self를 캡쳐하게 됩니다.NOTE asHTML 클로저는 지연 프로퍼티로 선언됐습니다. 왜냐하면 HTML를 렌더링 하기 위해 필요한 태그와 텍스트가 준비되고 나서야 그것의 HTML이 필요하기 때문입니다. 또 지연 프로퍼티이기 때문에 프로퍼티 안에서 self를 참조할 수 있습니다.
NOTE 위에서 paragraph 변수는 HTMLElement?로 선언됐습니다. 그래서 변수에 nil을 할당할 수 있지만 아래 그림과 같이 강한 참조 순환에 빠지게 됩니다.
NOTE 클로저 안에서 self를 여러번 참조하더라도 실제로는 단 한번의 강한 참조만 캡쳐합니다.
NOTE Swift에서는 클로저에서 특정 self의 메소드를 사용할 때 캡쳐를 실수하는 것을 막기위해 someProperty 혹은 someMethod 대신 self.someProperty 혹은 self.someMethod와 같이 self를 명시하는 것을 필요로 합니다.
NOTE 만약 캡쳐리스트가 절대 nil이 될 수 없다면 그것은 반드시 약한 참조 리스트가 아니라 미소유 참조 리스트로 캡쳐돼야 합니다.