GoogleMaps / GooglePlaces在iPhone上泄露内存 - 迅速

时间:2016-05-26 14:56:53

标签: ios iphone swift google-maps memory-leaks

我目前在我的应用中遇到问题。我有一个视图,我可以使用GoogleMaps / GooglePlaces SDK搜索并选择一个地方。我还使用Google自动填充功能完成搜索字符串。

问题:当我访问第一个视图时,一切仍然正常,但在我输入搜索字符串并按搜索后,我的内存使用量增加了大约10-20 MB。当我展开视图并保存它时,内存将不会被释放并且仍然在我的总内存中。因此,如果我保存了几个地方,我将获得溢出,应用程序将崩溃。 你们知道代码中我的问题在哪里吗?我已经找了几个小时...... 我查找了设置监听器的数据库请求,但事实上在这些类中没有任何相关的事情发生。也许它与Googlemaps有关,它可以保持连接吗?

我从我的应用程序附加了2个屏幕截图,其中2个类别如下:

enter image description here enter image description here

import UIKit
import GoogleMaps

class AddNewPlaceViewController: UIViewController, UISearchBarDelegate, LocateOnTheMap {

    //Outlets
    @IBOutlet weak var googleMapsContainer: UIView!

    //Variables
    var googleMapsView: GMSMapView!
    var searchResultController: SearchResultsController!
    var resultsArray = [String]()

    //Result
    var locationAsCoords = [String:Double]()
    var locationAdress = String()

    //Error
    var alerts = Alerts()
    var alertActions = AlertActions()


    override func viewDidLoad() {
        super.viewDidLoad()

    }

    override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(true)

        self.googleMapsView = GMSMapView(frame: self.googleMapsContainer.frame)
        self.view.addSubview(self.googleMapsView)

        searchResultController = SearchResultsController(view: self)
        searchResultController.delegate = self

        showSearchBar()
    }


    @IBAction func saveButtonTapped(sender: AnyObject) {

        if self.locationAdress.isEmpty {
            // Error message if no address has been searched
            NSLog("Event address ist empty.")
            let alert = alerts.alertNoLocationAddress
            let alertCancel = alertActions.alertActionCancel
            if(alert.actions.count == 0){
                alert.addAction(alertCancel)
            }
            self.presentViewController(alert, animated: true, completion: nil)

        } else {
            // exits with the saveAndUnwind segue
            self.performSegueWithIdentifier("saveAndUnwind", sender: self)
        }
    }

    /**
     action for search location by address

     - parameter sender: button search location
     */
    @IBAction func searchWithAddress(sender: AnyObject) {
        showSearchBar()
    }

    /**
     Locate map with latitude and longitude after search location on UISearchBar

     - parameter lon:   longitude location
     - parameter lat:   latitude location
     - parameter title: title of address location
     */
    func locateWithLongitude(lon: Double, andLatitude lat: Double, andTitle title: String) {

        dispatch_async(dispatch_get_main_queue()) { () -> Void in

            self.googleMapsView.clear()

            let position = CLLocationCoordinate2DMake(lat, lon)
            let marker = GMSMarker(position: position)

            let camera = GMSCameraPosition.cameraWithLatitude(lat, longitude: lon, zoom: 15)
            self.googleMapsView.camera = camera

            marker.title = "\(title)"
            marker.map = self.googleMapsView
        }
    }

    func showSearchBar(){
        let searchController = UISearchController(searchResultsController: searchResultController)
        searchController.hidesNavigationBarDuringPresentation = false
        searchController.searchBar.delegate = self
        self.presentViewController(searchController, animated: true, completion: nil)
    }

    /**
     Searchbar when text change

     - parameter searchBar:  searchbar UI
     - parameter searchText: searchtext description

     We can use filters here in the autocompleteQuery
     */
    func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {

        let placeClient = GMSPlacesClient()
        placeClient.autocompleteQuery(searchText, bounds: nil, filter: nil) { (results, error: NSError?) -> Void in

            self.resultsArray.removeAll()
            if results == nil {
                return
            }

            for result in results! {
                if let result = result as? GMSAutocompletePrediction {
                    self.resultsArray.append(result.attributedFullText.string)
                }
            }

            self.searchResultController.reloadDataWithArray(self.resultsArray)

        }
    }


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


    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

        if(segue.identifier == "saveAndUnwind"){

            //Pushing the data to the other view controller
            let destViewControllerCreateEventTable  = segue.destinationViewController as! CreateEventTableViewController

            destViewControllerCreateEventTable.locationAsCoords["latitude"] = self.locationAsCoords["latitude"]
            destViewControllerCreateEventTable.locationAsCoords["longitude"] = self.locationAsCoords["longitude"]
            destViewControllerCreateEventTable.locationAdress = self.locationAdress

            destViewControllerCreateEventTable.locationLabel.text = self.locationAdress
            destViewControllerCreateEventTable.locationLabel.textColor = UIColor.darkGrayColor()

        }

    }


}

//

import UIKit

protocol LocateOnTheMap{
    func locateWithLongitude(lon:Double, andLatitude lat:Double, andTitle title: String)
}

class SearchResultsController: UITableViewController {

    var searchResults: [String]!
    var delegate: LocateOnTheMap!

    var addNewPlaceReference = AddNewPlaceViewController()

    init(view: AddNewPlaceViewController ){
        super.init(style: UITableViewStyle.Plain)
        addNewPlaceReference = view
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        self.searchResults = Array()
        self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cellIdentifier")

    }

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

    // MARK: - Table view data source

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {

        return 1
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return self.searchResults.count
    }


    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("cellIdentifier", forIndexPath: indexPath)

        cell.textLabel?.text = self.searchResults[indexPath.row]
        return cell
    }



    override func tableView(tableView: UITableView,
        didSelectRowAtIndexPath indexPath: NSIndexPath){
            // 1
            self.dismissViewControllerAnimated(true, completion: nil)
            // 2
            let correctedAddress:String! = self.searchResults[indexPath.row].stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.symbolCharacterSet())
            let url = NSURL(string: "https://maps.googleapis.com/maps/api/geocode/json?address=\(correctedAddress)&sensor=false")

            let task = NSURLSession.sharedSession().dataTaskWithURL(url!) { (data, response, error) -> Void in
                // 3
                do {
                    if data != nil{
                        let dic = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableLeaves) as! NSDictionary

                        let lat = dic["results"]?.valueForKey("geometry")?.valueForKey("location")?.valueForKey("lat")?.objectAtIndex(0) as! Double
                        let lon = dic["results"]?.valueForKey("geometry")?.valueForKey("location")?.valueForKey("lng")?.objectAtIndex(0) as! Double
                        // 4
                        self.delegate.locateWithLongitude(lon, andLatitude: lat, andTitle: self.searchResults[indexPath.row])

                        self.addNewPlaceReference.locationAdress = self.searchResults[indexPath.row]
                        self.addNewPlaceReference.locationAsCoords["latitude"] = lat
                        self.addNewPlaceReference.locationAsCoords["longitude"] = lon

                    }

                }catch {
                    print("Error")
                }
            }
            // 5
            task.resume()
    }


    func reloadDataWithArray(array:[String]){
        self.searchResults = array
        self.tableView.reloadData()
    }

}

0 个答案:

没有答案