8

내보기에는 두 개의 다른 UIPickerView가 있습니다. 스토리 보드를 통해 호스팅되는 뷰에 dataSource 및 대리자를 설정할 때 훌륭한 기능을하지만, 아래에 설명 된대로 코드를 통해이를 수행하려고하면 작동하지 않습니다.Swift에서 "외부"DataSource 및 대리인이있는 UIPickerView

두 피커 모두 표시 할 데이터가 다르며 대리인의 다른 동작도 있어야합니다. 따라서 프로그래밍 방식으로 다른 데이터 소스에 연결하려고합니다.

UIPickerViewDataSource 및 UIPickerViewDelegate-Protocols를 구현하는 클래스를 만들고 해당 클래스의 개체를 PickerViews에 연결하려고했지만 작동하지 않습니다.

2015-01-09 17:50:05.333 Pet Stats[4953:244338] -[NSConcreteMapTable numberOfComponentsInPickerView:]: unrecognized selector sent to instance 0x7b4616d0 
2015-01-09 17:50:05.338 Pet Stats[4953:244338] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSConcreteMapTable numberOfComponentsInPickerView:]: unrecognized selector sent to instance 0x7b4616d0' 

가 어떻게이 작업을 얻을 수 있습니다 : 예외가이 진술 런타임 terminating with uncaught exception of type NSException 던져? 내가 놓친 게 무엇입니까? 여기 내 코드입니다 :

import UIKit 

class WeightWheelController: NSObject, UIPickerViewDelegate, UIPickerViewDataSource { 
    let ElementCount: Int! 

    init(pickerInterval: Int) { 
     ElementCount = pickerInterval 
    } 

    func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int { 
     return 1 
    } 

    func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { 
     return ElementCount 
    } 

    func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! { 
     return String(row + 1) 
    } 

    func pickerView(pickerView: UIPickerView!, didSelectRow row: Int, inComponent component: Int) 
    { 
     println("External Controller:" + String(row + 1)) 
    } 
} 

WeightWheelInputViewController.swift

WeightWheelController.swift

import UIKit 

class WeightWheelInputViewController: UIViewController { 
    @IBOutlet weak var picker1: UIPickerView!   
    @IBOutlet weak var picker2: UIPickerView! 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     //picker attached to c1 should show number from 1 to 150 
     let c1 = WeightWheelController(pickerInterval: 150) 

     //picker attached to c1 should show number from 1 to 10 
     let c2 = WeightWheelController(pickerInterval: 10) 

     picker1.dataSource = c1 
     picker1.delegate = c1 

     picker2.dataSource = c2 
     picker2.delegate = c2 
    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
    } 
} 

간단한 UPDATE : 나는 당신이 사용할 수있는 것으로 나타났습니다이 질문에

다른 선택기보기에 대해 다른 태그. 그것은 하나의 선택이 될 것입니다; 나는 그것을 좋아하지 않는다. 차라리 MVC 방식을 따르고 각 컨트롤러에 다른 컨트롤러를 연결하고 싶습니다. 어떤 식 으로든 가능하지 않습니까?

답변

13

delegatedatasource은 모두 소유주의 참조입니다. 즉, 범위를 벗어나면 c1c2이 출시됩니다. 클래스의 속성으로 c1c2을 선언 해보십시오.

소유되지 않은 참조는 참조 된 객체에 대해 강력한 보류를 생성하지 않습니다 (예 : ARC가 참조 된 객체의 할당을 해제하지 못하도록 보유 수를 늘리지 않음).

또한 인터페이스 작성기에서 pickerviews의 대리자 및 데이터 소스 속성을 제거해야합니다.

class WeightWheelInputViewController: UIViewController { 
    @IBOutlet weak var picker1: UIPickerView!   
    @IBOutlet weak var picker2: UIPickerView! 

    var c1 : WeightWheelController! 
    var c2 : WeightWheelController! 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     c1 = WeightWheelController(pickerInterval: 150) 

     c2 = WeightWheelController(pickerInterval: 10) 

     picker1.dataSource = c1 
     picker1.delegate = c1 

     picker2.dataSource = c2 
     picker2.delegate = c2 
    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
    } 
} 
+3

대단한 반응! 상자에서 바로 작업했습니다! 정말 고맙습니다!!! 내가 얻지 못하는 것은 이것입니다 : 자바에서는 위에서 코딩 한 것을 할 수 있으며 GC는 PickerView에 의해 참조되기 때문에 "약한"참조가있는 객체를 수집하지 않습니다. 어떻게 신속하게 다른 처리합니까? – Christian

+0

잘. 자동 참조 카운팅 (ARC)에 대해 알아야합니다. 사과에 관한 문서를 읽어 보시기 바랍니다. https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html – rakeshbs

+1

엄청난 답변입니다. 나는 바보가되고 있었다. 대단히 감사합니다! –