ios - 未调用IBOutlet类init,成员为nil

时间:2015-01-29 19:04:18

标签: ios iphone swift iboutlet

我正在尝试将搜索功能添加到我在XCode 6上的swift上工作的基于地图的项目。我已将SearchDisplayController添加到我的主视图控制器,其中包含地图。我创建了一个名为MapSearchDisplayController的类,它实现了必要的方法。我还将SearchDisplayController的Custom Class属性更改为故事板中的MapSearchDisplayController。

在故事板中,我将SearchDisplayController拖到我的主视图控制器上以创建IBOutlet。我对主视图控制器的主viewDidLoad如下所示:

class ViewController: UIViewController, CCHMapClusterControllerDelegate, MKMapViewDelegate, ADBannerViewDelegate {

    @IBOutlet weak var mapSearchDisplayController1: MapSearchDisplayController!
    @IBOutlet var mapSearchDisplayController: MapSearchDisplayController!
    @IBOutlet weak var banner: ADBannerView!
    @IBOutlet weak var mMap: MKMapView!
    var clusterController:CCHMapClusterController?
    let mMaxZoomLevelForClustering : Double = 13
    let mMinUniqueLocationsForClustering : UInt = 1
    var formatter = NSNumberFormatter()

    var databasePath = NSString()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        banner.delegate = self

        // Add button to navbar
        var filterButton : UIBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Organize, target: self, action: nil)
        self.navigationItem.leftBarButtonItem = filterButton

        var aboutButton : UIBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Add, target: self, action: "aboutAction")
        var searchButton : UIBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Search, target: self, action: "searchAction")
        var rButtons : [UIBarButtonItem] = [aboutButton, searchButton]
        self.navigationItem.rightBarButtonItems = rButtons


        // Deal with Search Display Controller
        self.mapSearchDisplayController.delegate = self.mapSearchDisplayController;
        self.mapSearchDisplayController.searchResultsDataSource = self.mapSearchDisplayController;
        self.mapSearchDisplayController.searchResultsDelegate = self.mapSearchDisplayController;
        self.mapSearchDisplayController.searchBar.placeholder = "Search Destination";
        self.mapSearchDisplayController.searchResultsTableView.delegate = self.mapSearchDisplayController
        self.mapSearchDisplayController.searchResultsTableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "Cell")

问题1:我必须添加一个额外的mapSearchDisplayController 1 - 否则我的mapSearchDisplayController是nil,当我尝试使用它时我遇到了异常。现在,当我有一个额外的变量mapSearchDisplayController 1 (它被声明但从未使用过)时,它不会抛出异常并且某些功能正在运行。试图添加/删除,但它没有任何区别。我无法弄清楚我错过了什么导致这种行为。

Isse 2:我遇到的更大问题是,处理搜索相关功能的mapSearchDisplayController的实例变量是nil,它的init方法没有被调用,但是函数在委托方法有效。因此,data1变量为nil,尽管被初始化为硬编码字符串数组。所有其他成员也一样,包括googleAPIKey,这是一个常量。如果shouldReloadTableForSearchString再次设置data1 data1 = ["1111", "222", "ZAAAA"]然后它仍然被初始化,但是如果我将data1作为searchresult分配给它 - 它就会丢失。我会理解,如果整个对象是nil,但是方法正在被调用和工作,它只是一个实例变量和init,它们不是“工作”。代码如下:

class MapSearchDisplayController: UISearchDisplayController, UISearchDisplayDelegate, UITableViewDataSource, UITableViewDelegate, LPGoogleFunctionsDelegate
{
    var data1 : [String]! = ["1111", "222", "ZAAAA"]
    var googleFunctions : LPGoogleFunctions? = LPGoogleFunctions()
    let googleAPIKey = "myKey"
    //MARK: UITableViewDelegate

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        println("In numberOfRowsInSection - \(data1.count)")
        return self.data1.count
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        println("In cellForRowAtIndexPath")
        var cell = tableView.dequeueReusableCellWithIdentifier("Cell") as? UITableViewCell
        if !(cell != nil) {
            println("new cellForRow")
            cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell")
        }
        // Get the corresponding candy from our candies array
        let candy = self.data1[indexPath.row]

        // Configure the cell
        cell!.textLabel.text = candy
        cell!.detailTextLabel?.text = "Cell Details"
        return cell!
    }   

    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        tableView.deselectRowAtIndexPath(indexPath, animated: true)
        // Dismiss search display controller
        self.active = false;

        // Force selected annotation to be on map
    }


    func tableView(tableView: UITableView, numberOfSectionsInTableView indexPath: NSIndexPath) -> Int{
        println("numberOfSectionsInTableView")
        return 1
    }

    //MARK: Search methods
    func filterContentForSearchText (searchText: String) {
        println(searchText)
    }

    func searchDisplayController(controller: UISearchDisplayController!, shouldReloadTableForSearchString searchString: String!) -> Bool {
        var  length : Int32 = Int32(countElements(searchString))
        if (countElements(searchString) < 3 ) {
            println("Short searchString. Not enough info")
            return false
        }
        data1 = []
        if (googleFunctions == nil)
        {
            googleFunctions = LPGoogleFunctions()
            googleFunctions!.sensor = false
            googleFunctions!.delegate = self
            googleFunctions!.googleAPIBrowserKey = "myKey"
        }
        println(googleFunctions?.googleAPIBrowserKey)
        googleFunctions?.loadPlacesAutocompleteWithDetailsForInput(searchString, offset: length, radius: 0, location: nil, placeType: LPGooglePlaceTypeGeocode, countryRestriction: nil, successfulBlock: {(pd : [AnyObject]!) in
            println("--------------GOOGLE search success")

            for place in pd{
                var pl = place as LPPlaceDetails
                self.data1.append(pl.name)
                println(pl.name)
            }
            }
            , failureBlock: {(status : LPGoogleStatus) in
            println("---- GOOGLE failed")
            })
        //data1 = ["1111", "222", "ZAAAA"]
        return true
    }

    func searchDisplayControllerWillBeginSearch(controller: UISearchDisplayController!){
        controller.searchBar.showsCancelButton = true
    }

    func searchDisplayControllerWillEndSearch(controller: UISearchDisplayController!){
        println("searchDisplayControllerWillEndSearch")
    }

    //MARK: LPGogleFunctions methods
    override init() {

        println("Initializing GoogleFunctions")
        if (googleFunctions == nil){
            googleFunctions = LPGoogleFunctions()
        }
        data1 = []
        super.init()

        googleFunctions!.sensor = false
        googleFunctions!.delegate = self
        googleFunctions!.googleAPIBrowserKey = "myKey"
    }
}

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

我正在回答我自己的问题,万一有人遇到同样的问题。

问题#1我通过删除两个IBOutlet并在故事板中重新添加它来解决这个问题。

发布#2:我没有调用searchResultsTableView.reloadData()。 由于网络调用是异步的,因此在更新tableview之后会在lambda中收到结果。强制更新可以解决问题。