2017-12-04 3 views
0

Ich verwende MapKit, um CLLocationManagerDelegate zu verwenden, um den Standort des Benutzers abzurufen. Wenn ich in der ViewController-Funktion viewDidLoad() nach dem Standort des Benutzers fragen möchte, wird ein Popup angezeigt, in dem der Benutzer nach der Eingabe des Benutzers gefragt wird. Hinweis: Die beiden Eigenschaften für den Standort fragen erforderlich (Ort bei Gebrauch und Ort immer Und bei Gebrauch) wird hinzugefügtWarum verschwindet das Popup "locationManager" sofort, wenn es in einer anderen Klasse verwendet wird?

, die auf info.plist ist,

import UIKit 
import MapKit 
class ViewController: UIViewController, CLLocationManagerDelegate { 
     var locationManager: CLLocationManager? 

     override func viewDidLoad() { 
      super.viewDidLoad() 
      locationManager = CLLocationManager() 
      self.locationManager?.desiredAccuracy = kCLLocationAccuracyBest 
      self.locationManager?.requestWhenInUseAuthorization() 
      self.locationManager?.delegate = self 
      self.locationManager?.startUpdatingLocation() 
     } 
} 

Der obige Code funktioniert gut ; Wenn das Programm beginnt, wird ein Popup angezeigt, in dem der Benutzer nach seinem Standort gefragt wird.

jedoch Wenn ich in dieser Klasse eine neue Klasse MapController und setzen den gleichen Code zu erstellen war, und eine neue Instanz von MapController innerhalb viewDidLoad() erstellen, dann das Popup verschwindet sofort, wenn das Programm ausgeführt wird.

Das heißt,

import UIKit 
class ViewController: UIViewController { 

    override func viewDidLoad() { 
      super.viewDidLoad() 
      let mapController = MapController(viewController: self) 
      mapController.initialise() 
    } 
} 

import MapKit 
class MapController: NSObject, CLLocationManagerDelegate { 
     private let viewController: UIViewController 
     private var locationManager: CLLocationManager 

     required init(viewController: UIViewController) { 
      self.viewController = viewController 
      locationManager = CLLocationManager() 
     } 

     func initialise() { 
      self.locationManager.desiredAccuracy = kCLLocationAccuracyBest 
      self.locationManager.requestWhenInUseAuthorization() 
      self.locationManager.delegate = self 
      self.locationManager.startUpdatingLocation() 
     } 
} 

Wenn der Code oben ausgeführt wird, das Pop-up für die Position des Benutzers zu fragen verschwindet sofort.

Meine Frage ist: Warum bleibt das Popup, wenn der locationManager Code in der viewDidLoad() ist, aber wenn der Code in eine andere Klasse getrennt und in viewDidLoad() aufgerufen wird, verschwindet es sofort. Warum passiert das?

Wie kann ich den locationManager Code in eine andere Klasse trennen, ohne dass das Popup sofort verschwindet?

+0

Sie sollten nicht unbedingt 'requestWhenInUseAuthorization' aufrufen. Sie sollten immer 'CLLocationManager.authorizationStatus' zuerst überprüfen und entsprechend handeln. Machen Sie darüber hinaus keine Klasse von "NSObject" abhängig, es sei denn, Sie haben einen Grund dafür. In Swift müssen Klassen nicht von einer Basisklasse erben. –

+0

@ DávidPásztor Wenn ich nicht von NSObject erben, von welcher Klasse sollte ich erben? MapController muss 'NSObject' erben, andernfalls wird der Fehler 'MapController entspricht nicht dem Protokoll NSObjectProtocol' zurückgegeben. – instig

Antwort

1

Es ist ein Speicherverwaltungsproblem. In ViewController erstellen Sie eine lokale Variable mit dem Namen mapController in viewDidLoad. Am Ende der viewDidLoad, die MapController Instanz geht aus dem Geltungsbereich und wird freigegeben.

Anstatt eine lokale Variable in viewDidLoad zu verwenden, erstellen Sie eine Eigenschaft.

class ViewController: UIViewController { 
    var mapController: MapController! 

    override func viewDidLoad() { 
      super.viewDidLoad() 

      mapController = MapController(viewController: self) 
      mapController.initialise() 
    } 
} 

Aber das schafft nun einen Referenzzyklus seit MapController ist eine starke Bezugnahme auf die View-Controller zu halten.

Sie müssen also auch die viewController Eigenschaft von MapController zu weak ändern.

Verwandte Themen