기본값 또는 기본 종료 값을 사용하는 저장된 속성의 경우 메모리가 균등하게 할당되고 init
메서드가 호출됩니다. self
또는 속성을 기본값으로 다른 속성을 정의하는 데 사용할 수 없습니다.
이 단계에서 보통 lazy
속성을 정의하는 데 사용되는 클로저입니다. 게으른 속성에 대한
메모리가 먼저 속성 전화에 할당됩니다 : 그들은 var
및 lazy
키워드로 표시해야한다. Construction {/*...*/}()
은이 클로저가 호출 순간에만 실행되고 계산 결과를 반환한다는 것을 의미합니다 (이름없는 함수 에서처럼이 클로저를 볼 수 있음).이 클로저는 참조하지 않습니다. 이것은 매우 중요한 순간입니다 : 클로저를 유지하지 않으면이 클로저는 실행 순간에만 할당하고 반환 직후 할당을 취소하므로 강력한 순환 참조 문제에 신경 쓸 필요가 없습니다.
다른 것은 - 당신이 폐쇄에 대한 참조를 저장할 때이 클로저
class myClass {
let x: NSString? = nil
var closure:() -> NSString = {return "q"} //allocates before class init; deallocates on references release
lazy var lazyClosure:() -> NSString = {
let z = self.x
return z ?? ""
} //allocates on first property call; deallocates on references release
}
메모리는 앞의 경우에서와 같은 시간에 할당하지만 그들이 어떤 참조가 될 때까지 살 것입니다. 별도의 객체처럼 여기에서 클로저를 볼 수 있습니다. 사이클 참조 문제가 발생할 수 있습니다. closure
은 아무 것도 캡처하지 않으므로 아무런 문제가 없지만 lazyClosure
캡쳐 self
입니다. 우리가 결코 lazyClosure
으로 전화하지 않으면 아무런 문제가 없을 것입니다. 왜냐하면이 폐쇄는 결코 할당하지 않을 것이기 때문입니다. 그러나 우리가 그것을 호출하면 할당되고, self
을 포착하고, 강한 순환 참조가있을 것입니다. self
은 lazyClosure
인스턴스를 가리키고, lazyClosure
은 self
인스턴스를 가리 킵니다. 이 문제를 해결하려면 참조 중 하나를 약하게 만들어야합니다. 캡처 목록을 사용해야합니다. [weak self] in
또는 [unowned self] in
을 lazyClosure
본문에 삽입해야합니다. [unowned self] in
우리의 경우, 속성이 호출되면 self
이 nil
이 아니기 때문입니다.
lazy var lazyClosure:() -> NSString = {
[unowned self] in
let z = self.x
return z ?? ""
}
게시물이 너무 광범위하고, 질문의 일부는 이미 http://stackoverflow.com/questions/32693150/whats-wrong-here-instance-member-cannot-be 예를 들어보고, 여기에 대답했다 -used-on-type – Cristik
@Cristik 내 질문을 편집했습니다. 수정 된 질문에 대답 해 주시겠습니까? 감사. –