报错信息: unrecognized selector sent to * 的定位和解决

2015-06-16 15:03:15.852 UIViewDemo[7826:720287] -[UIViewController numberOfComponentsInPickerView:]: unrecognized selector sent to instance 0x7f8092736f60
2015-06-16 15:03:15.857 UIViewDemo[7826:720287] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIViewController numberOfComponentsInPickerView:]: unrecognized selector sent to instance 0x7f8092736f60'
*** First throw call stack:
(
...

If you look at the error message you see that the method numberOfComponentsInPickerView: was invoked on a UITableView instance.

So you ask the question "why would that method be invoked on a UITableView?"

The method in question is a picker view data source method, so that means that somewhere you assigned a UITableView as a picker view's data source, so that when the picker view was displayed the method call was made against a class (UITableView) that hadn't implemented the delegate method.

In your case it was a simple drag-drop error in Interface Builder.

从错误信息看到程序调用到了一个UIViewController的numberOfComponentsInPickerView方法, 而实际上这个方法是UIPickerViewDataSource的方法, 所以这就意味着指定了一个UIViewController作为pickerView的datasource, 这明显是不对的. 检查以后发现, 果然是没有把当前的viewControll类指定为datasource.

顺便记一下, 指定datasource的方式有两种

  1. drag-drop Alt text

  1. 继承UIPickerViewDataSource和UIPickerViewDelegate, 并指定pickerView的delegate和dataSource是self
import UIKit

class MyPickViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate{

    var colors = ["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"]

    @IBOutlet weak var myPicker: UIPickerView!
    override func viewDidLoad() {
        super.viewDidLoad()
        myPicker.delegate = self
        myPicker.dataSource = self

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    // pragma MARK: UIPickerViewDataSource Delegate

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


    func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return colors.count
    }

    // pragma MARK: UIPickerViewDelegate

    func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! {
        return colors[row]
    }
}
2015-06-28 15:1739