2014-11-19 2 views
9

HMSegmentedControl에서 segmentedControl.indexChangeBlock을 인스턴스 메서드로 설정하여 작업을 처리하고 싶습니다. 공식 예는 https://github.com/HeshamMegid/HMSegmentedControl/blob/master/HMSegmentedControlExample/HMSegmentedControlExample/ViewController.m (63 ~ 68 행)이지만 Objective-C입니다.Swift에서 클로저/함수에 대한 약한 참조를 설정하는 방법은 무엇입니까?

스위프트에서 함수는 일급 시민입니다. 그래서이 블록 속성에 인스턴스 메서드를 설정하고 싶습니다.

class ExampleVC: UIViewController { 
    var segmentedControlIndex: Int = 0 

    override func viewDidLoad() { 
     let segmentedControl3 = HMSegmentedControl(sectionImages: ... , sectionSelectedImages: ...) 
     segmentedControl3.frame = ... 
     segmentedControl3.indexChangeBlock = someInstanceMethod 
    } 

    func someInstanceMethod(index: Int) { 
     segmentedControlIndex = index 
    } 
} 

그러나, 나는 비 클래스 형에 약한 참조를 정의 할 수 없습니다 :
하지만 내 코드는 순환 참조로 이어질 것, 내가 약한 참조를 정의해야합니다 것 같다. 내가 무엇을 할 수 있을지? 이것을하는 것이 합법적입니까?

+0

가능한 중복 [스위프트의 방법으로 자기가 약합니다 ... 항상 안전 ] (http://stackoverflow.com/questions/25613783/make-self-weak-in-methods-in-swift) – user102008

답변

4

클로저에 약한 참조를 정의하는 대신 클로저에 "Capture List"을 사용해야합니다.

segmentedControl3.indexChangeBlock = { [unowned self] in self.someInstanceMethod($0) } 

내가 아는 한, 이것은 강력한 참조주기를 피할 수있는 유일한 방법입니다.

+3

'[weak self]'는 참조주기를 깨뜨리고 일반적으로 코드가 생성 될 때 파손되기 쉽지 않습니다. 리팩토링 또는 뷰 계층이 재구성됩니다. –

12

[unowned self]은 위험합니다. 이것이 말하는 것은 런타임에 '자기가 공개되지 않았다고 가정하고 검사하는 것에 대해 걱정하지 마십시오.'라고 말합니다. 그 동안에 self이 출시되면 귀하의 신청서는 SEGFAULT됩니다.

이 경우 { [weak self] in self?.someInstanceMethod($0) }은 참조주기를 중단하고 self이 해제되면 no-op으로 바뀝니다. (예를 들어, 뷰 계층 등) 코드의 다른 영역을 수정하면 [unowned self] 앱 충돌을 도입 할 수있는 동안

[weak self]은의

+0

HMSegmentedControl은 ExampleVC에서 소유하므로 절대로 자체가 없어야합니다. 그리고 애플은 말하기를 : 언제든지 소유하지 않는 것이 가능하다. – Dam

+1

Unowned는 여전히 근본적으로 안전하지 않습니다. 나는 애플이 권장하는 것을 따라하는 것이 좋다는 것을 알고있다. 그리고 이것은 아마도 성능상의 이유 일 것이다. 그러나 필자가 설명한 이유 때문에 필자는 필자의 권고에 따른다. –

+1

나는 당신에게 동의한다, 약한 항상 안전 할 것이다. 요점은 그냥 공개되지 않는다고 가정하지 않는다는 것입니다. 더 많은 개발자가 될 것입니다. 그러나 나는 또한 당신이 누군가가 그것이 안전하다고 말하게하는 것보다 100 % 확실하다는 점에 동의한다. 점프. – Dam

관련 문제