ios - IBOutlet class 未调用初始化且成员为零
ios - IBOutlet class init not called and members are nil
我正在尝试向我在 XCode swift 中从事的基于地图的项目添加搜索功能 6. 我已将 SearchDisplayController 添加到包含地图的主视图控制器。我创建了一个名为 MapSearchDisplayController 的 class,它实现了必要的方法。我还在故事板中将 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: 我必须添加一个额外的 mapSearchDisplayController1 - 否则我的 mapSearchDisplayController 为零,我在尝试时出现异常去使用它。现在,当我有一个额外的变量 mapSearchDisplayController1 (已声明但从未使用过)时,它不会抛出异常并且某些功能正在运行。尝试 add/remove weak,但它没有任何区别。我不知道我错过了什么导致了这种行为。
问题 2: 我遇到的更大的问题是,处理搜索相关功能的 mapSearchDisplayController 的实例变量为 nil,它的 init 方法未被调用,但委托方法中的功能有效。因此,尽管已初始化为硬编码字符串数组,但 data1 变量为 nil。所有其他成员也是如此,包括常量 googleAPIKey。如果 shouldReloadTableForSearchString 再次设置 data1 data1 = ["1111", "222", "ZAAAA"]
那么它会保持初始化状态,但是如果我为 data1 分配我作为搜索结果获得的值 - 它会丢失。我会理解如果整个对象为零,但方法正在被调用和工作,它只是一个实例变量和 init 不是 "working"。代码如下:
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 我通过删除 IBOutlets 并在故事板中重新添加它们来解决。
发出 #2:我没有调用 searchResultsTableView.reloadData()。
由于网络调用是异步的,因此在更新表视图后在 lambda 中收到结果。强制更新解决了这个问题。
我正在尝试向我在 XCode swift 中从事的基于地图的项目添加搜索功能 6. 我已将 SearchDisplayController 添加到包含地图的主视图控制器。我创建了一个名为 MapSearchDisplayController 的 class,它实现了必要的方法。我还在故事板中将 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: 我必须添加一个额外的 mapSearchDisplayController1 - 否则我的 mapSearchDisplayController 为零,我在尝试时出现异常去使用它。现在,当我有一个额外的变量 mapSearchDisplayController1 (已声明但从未使用过)时,它不会抛出异常并且某些功能正在运行。尝试 add/remove weak,但它没有任何区别。我不知道我错过了什么导致了这种行为。
问题 2: 我遇到的更大的问题是,处理搜索相关功能的 mapSearchDisplayController 的实例变量为 nil,它的 init 方法未被调用,但委托方法中的功能有效。因此,尽管已初始化为硬编码字符串数组,但 data1 变量为 nil。所有其他成员也是如此,包括常量 googleAPIKey。如果 shouldReloadTableForSearchString 再次设置 data1 data1 = ["1111", "222", "ZAAAA"]
那么它会保持初始化状态,但是如果我为 data1 分配我作为搜索结果获得的值 - 它会丢失。我会理解如果整个对象为零,但方法正在被调用和工作,它只是一个实例变量和 init 不是 "working"。代码如下:
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 我通过删除 IBOutlets 并在故事板中重新添加它们来解决。
发出 #2:我没有调用 searchResultsTableView.reloadData()。 由于网络调用是异步的,因此在更新表视图后在 lambda 中收到结果。强制更新解决了这个问题。