2016-08-14 4 views
6

샘플 코드에서 두 가지 스타일의 선언 객체를 보았습니다. 하나의 장점은 다른 것보다 무엇입니까?이 두 선언 스타일 간의 차이점은 무엇입니까

모두 선언 한 스타일 var btn: UIButton!

등 :

btn = UIButton() 
btn.translatesAutoresizingMaskIntoConstraints = false 
btn.layer.borderColor = UIColor.blue.cgColor 
btn.layer.borderWidth = 1 
... 
self.view.addSubview(btn) 

스타일 2 :

btn = { 
    let b = UIButton() 
    b.translatesAutoresizingMaskIntoConstraints = false 
    b.layer.borderColor = UIColor.blue.cgColor 
    b.layer.borderWidth = 1 
    ... 
    return b 
}() 
self.view.addSubview(btn) 

나는 현재 볼 수있는 유일한 장점은 두 번째 스타일 브랜드입니다 많은 obj가있을 때 더 읽기 쉬운 코드 ects. 또한 Xcode로 축소 할 수 있습니다. 다른 장점이 있습니까? 두 번째 버전은 런타임에 더 많은 리소스를 "비용"을 지불하지 않습니까? 어느 것이 좋습니다?

감사

+0

차이점이 있는지는 모르겠지만 두 번째 패턴은 모든 설정이 완료된 후에 만 ​​할당됩니다 (즉, 오류가 발생하면 'btn'을 반 초기화하지 않음) . – Thilo

+0

나는이 것이 유용하다고 생각한다. 생성시에 어떤 값을 변경/할당해야하는 객체를 생성하고자 할 때 (예 : 선택적 속성을 가진 구조체와 init 메소드는 그것을 할당 할 수 없습니다). 그러나 동시에 변수 자체를 불변으로 유지하려고합니다. – Surely

+0

버튼을 암시 적으로 래핑되지 않은 옵션으로 선언하면 안됩니다. – nhgrif

답변

3

클로저 초기화 (두 번째 예)에는 세 가지 큰 이점이 있습니다.

이점 1 : 초기화 let 구조체. 귀하의 예는 참조 유형 인 클래스 인 UIButton을 사용합니다. 구조체를 let으로 초기화하는 경우이를 변형 할 수 없습니다. 우리는 어떤 setter도 변경할 수 없으며, 으로 표시된 메소드를 let 선언으로 초기화하면 호출 할 수 없습니다. 클로저 초기화는 let - 선언 된 변수에 할당하기 전에이 작업을 수행 할 수있게 해줍니다.

이점 2 : 범위. 우리가 초기화하는 클로저는 자체 범위를 갖습니다. 범위를 포함하는 변수를 캡처 할 수 있지만 범위 내에서 선언 된 변수는 변수 외부에서 사용할 수 없습니다. 이것은 변수 이름에 충돌이 없다는 것을 의미합니다. 또한 초기화가 완료되면 ARC가 일부 정리 작업을 수행 할 수 있음을 의미합니다.

이점 3 : 클래스/구조체 멤버 변수의 인라인 초기화. 내가 처음 나열한 두 가지 장점은 항상 필요한 것은 아니며 대개 주위에서 해결할 수 있습니다. 당신이이 선언 된 지점에서 버튼을 초기화하고 싶어하지만 폐쇄 초기화하지 않고,이 같은 뭔가 붙어 있습니다

class MyViewController: UIViewController { 

    var button = UIButton() 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     // TODO: Set up button's properties 

     view.addSubview(button) 
    } 
} 

그러나 폐쇄 초기화, 우리는 그 모든 지점에서 설정 설정할 수 있습니다 선언.

class MyViewController: UIViewController { 

    var button: UIButton = { 
     let button = UIButton() 
     // TODO: Set up button 
     return button 
    }() 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     view.addSubview(button) 
    } 
} 
1

의 차이는 작은 예에 상당히 사소한하지만 더 크고 복잡한 소프트웨어에 더 중요 할 수있다.

첫 번째 예에서는 모든 속성 할당이 완료 될 때까지 상태 btn이 일시적으로 유효하지 않습니다. 두 번째 예에서는 버튼이 btn에 할당되면 완전히 빌드됩니다. 또한 두 번째 코드는 사실상 별도의 클래스로 분리되고 매개 변수화 된 팩터 리 메서드입니다. 유사한 버튼이 많이 생성되는 경우 유용합니다.

단추 및 기타 컨트롤을 전문가 클래스로 작성하는 책임을 분리하는 것은 iOS 앱에서보기 컨트롤러의 크기와 복잡성을 줄이기위한 훌륭한 단계입니다.

관련 문제