Ios 如何获取对已实例化的ViewController的引用?

Ios 如何获取对已实例化的ViewController的引用?,ios,swift,uiviewcontroller,swift2,core-location,Ios,Swift,Uiviewcontroller,Swift2,Core Location,这里是敏捷的新手。我正在尝试让我的简单核心位置应用程序在通过locationManager获取坐标后自动检索数据。 我已经实现了单独的类,以使我的主视图控制器不负责太多的任务 import Foundation import CoreLocation class CoreLocationController : NSObject, CLLocationManagerDelegate { var locationManager = CLLocationManager() var lastCo

这里是敏捷的新手。我正在尝试让我的简单核心位置应用程序在通过
locationManager
获取坐标后自动检索数据。 我已经实现了单独的类,以使我的主视图控制器不负责太多的任务

import Foundation
import CoreLocation

class CoreLocationController : NSObject, CLLocationManagerDelegate {

var locationManager = CLLocationManager()

var lastCoordinates: (lat: Double, lon: Double)?

override init() {  
    super.init()
    self.locationManager.delegate = self
    self.locationManager.requestWhenInUseAuthorization()
    self.locationManager.distanceFilter  = 3000
    self.locationManager.desiredAccuracy = kCLLocationAccuracyKilometer

}

func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {

    let location = locations.last! as CLLocation

    self.lastCoordinates = (location.coordinate.latitude, location.coordinate.longitude)
    print("didUpdateLocations:  \(location.coordinate.latitude), \(location.coordinate.longitude)")

}

func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
    print("didChangeAuthorizationStatus")

    switch status {
    case .NotDetermined:
        print(".NotDetermined")
        break

    case .AuthorizedWhenInUse:
        print(".AuthorizedWhenInUse")
        self.locationManager.startUpdatingLocation()
        break

    case .Denied:
        print(".Denied")
        break

    default:
        print("Unhandled authorization status")
        break

    }
}

func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
   }
}

当然,我已经在AppDelegate.swift中初始化了它

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

var window: UIWindow?

var coreLocationController: CoreLocationController?

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

    self.coreLocationController = CoreLocationController()
    return true
}
现在,单击按钮后,我的主
ViewController
正在执行
retrieveWeatherForecast
,并将
appDelegate
传递给它以获取对
CoreLocationController.lastCoordinates
属性的引用。我得出的结论是,为了在启动后立即获取坐标后执行
retrieveWeatherForecast
,最好的方法是在
locationManager
func(带有
didUpdateLocations
参数的函数)中运行此方法。为了做到这一点,我需要参考
ViewController
运行实例来执行以下操作:

runningViewControlerinstance.retrieveWeatherForecast(runningViewControlerinstance.appDel)
ViewController
代码:

import UIKit

class ViewController: UIViewController {

@IBOutlet weak var currentTemperatureLabel: UILabel?
@IBOutlet weak var currentHumidityLabel: UILabel?
@IBOutlet weak var currentPrecipitationLabel: UILabel?
@IBOutlet weak var currentWeatherIcon: UIImageView?
@IBOutlet weak var currentWeatherSummary: UILabel?
@IBOutlet weak var refreshButton: UIButton?
@IBOutlet weak var activityIndicator: UIActivityIndicatorView?

let appDel = UIApplication.sharedApplication().delegate! as! AppDelegate

private var forecastAPIKey: String?

override func viewDidLoad() {
    super.viewDidLoad()

    let path = NSBundle.mainBundle().pathForResource("APIkeys", ofType: "plist")
    let dict = NSDictionary(contentsOfFile: path!)

    self.forecastAPIKey = dict!.objectForKey("forecastAPIKey") as? String

}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}

func retrieveWeatherForecast(appDel: AppDelegate ) {
    let currentCoordinates :(lat: Double, lon: Double) =  (appDel.coreLocationController?.lastCoordinates)!

    let forecastService = ForecastService(APIKey: forecastAPIKey!)
    forecastService.getForecast(currentCoordinates.lat, lon: currentCoordinates.lon) {
        (let currently) in

        if let currentWeather = currently {

            dispatch_async(dispatch_get_main_queue()) {

                if let temperature = currentWeather.temperature {
                    self.currentTemperatureLabel?.text = "\(temperature)º"
                }

                if let humidity = currentWeather.humidity {
                    self.currentHumidityLabel?.text = "\(humidity)%"
                }

                if let precipitation = currentWeather.precipProbability {
                    self.currentPrecipitationLabel?.text = "\(precipitation)%"
                }

                if let icon = currentWeather.icon {
                    self.currentWeatherIcon?.image = icon
                }

                if let summary = currentWeather.summary {
                    self.currentWeatherSummary?.text = summary
                }

                self.toggleRefreshAnimation(false)

            }


        }
    }
}

@IBAction func refreshWeather() {
    toggleRefreshAnimation(true)
    retrieveWeatherForecast(appDel)
}

func toggleRefreshAnimation(on: Bool) {
    refreshButton?.hidden = on
    if on {
        activityIndicator?.startAnimating()
    } else {
        activityIndicator?.stopAnimating()
    }
 }
}

我将非常感谢来自swift社区的任何帮助、意见和建议,谢谢

如果您有一个单独的类来处理位置服务(这是一个很好的设计模式)或应用程序委托,通知任何活动视图控制器的最佳方式是通过
NSNotification

通过
视图中的
NSNotificationCenter
在视图控制器中注册,并在
视图中将自己作为观察者删除将消失
。有大量的文档来解释细节

控制器与异步进程的这种松耦合比保留对UI对象的引用要安全得多

“当然我已经在AppDelegate.swift中初始化了它”
为什么?没有理由在那里初始化它,是吗?在您打算使用它的地方初始化它。viewController需要访问CoreLocationController才能使用、显示或编辑位置。因此,在那里初始化并使用它,您就不必将视图控制器传递给位置管理器。

这可能会导致多个核心位置控制器。这里的单例模式显然更可取。因为它是swift,所以在CoreLocationController中声明一个静态变量(也是一个惰性变量)也是可能的。