如何在定时器选择器上传递参数

7
  func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        guard let mostRecentLocation = locations.last else {
            return
        }

        print(mostRecentLocation.coordinate.latitude)
        print(mostRecentLocation.coordinate.longitude)        
        Timer.scheduledTimer(timeInterval: 60.0, target: self, selector: #selector(StartTestVC.sendDataToServer), userInfo: nil, repeats: true)
    }

    func sendDataToServer (latitude: Double, longitude: Double) {
        SFUserManager.shared.uploadPULocation(latitude, longitude:longitude)
    }

我希望每隔1分钟向服务器发送数据。我正在使用Timer.scheduledTimer并设置selector。但是如何将lat/lng参数发送到我的函数中呢?


你可以将你的位置作为类变量并发送。 - Reinier Melian
是的,我知道要通过选择器发送什么? - pmb
@pmb,你只需要摆脱输入参数,直接在函数内部使用类属性即可。请参见下面的答案。 - Dávid Pásztor
3个回答

8

如果您想使用Timer发送数据,可以使用userInfo参数来传递数据。

以下是示例代码,您可以通过调用选择器方法并将位置坐标传递给它来实现此功能。

Timer.scheduledTimer(timeInterval: 0.5, target: self, selector:#selector(iGotCall(sender:)), userInfo: ["Name": "i am iOS guy"], repeats:true)

处理userInfo的方法如下。

func iGotCall(sender: Timer) {
    print((sender.userInfo)!)
}

对于您的情况,请确保您的didUpdateLocations被频繁调用。


为什么我设置了每1秒调用一次iGotCall,它还是每秒都被调用了? - pmb
一分钟内,timeInterval应该是60,因此timeInterval为60。 - Maulik Pandya
是的,我知道我将它设置为60,但它会延迟60秒,然后每1秒调用IGotCall。 - pmb
你是否在其他地方调用了iGotCall函数? - Maulik Pandya
不,它不叫这个名字。 - pmb
显示剩余2条评论

1

确保sendDataToServer始终上传最新的坐标而无需将坐标作为输入参数输入函数的一种方法是将这些值存储在一个范围内,该范围可以被函数访问并在函数内部使用这些值。

假设您将mostRecentLocation设置为类属性,则可以使用以下代码:

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    guard let mostRecentLocation = locations.last else {
        return
    }   

    self.mostRecentLocation = mostRecentLocation
    Timer.scheduledTimer(timeInterval: 60.0, target: self, selector: #selector(StartTestVC.sendDataToServer), userInfo: nil, repeats: true)
}

func sendDataToServer() {
    SFUserManager.shared.uploadPULocation(self.mostRecentLocation.coordinate.latitude, longitude:self.mostRecentLocation.coordinate.longitude)
}

@Dnvid,但sendDataToServer根本没有被调用。 - pmb
更改之前它工作了吗?您在问题中没有提到它未被调用。如果以前也没有工作,那么didUpdateLocations是否被调用了? - Dávid Pásztor

0

这正是 userInfo 参数的用途所在:

struct SendDataToServerData { //TODO: give me a better name
    let lastLocation: CLLocation
    // Add other stuff if necessary
}

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    guard let mostRecentLocation = locations.last else { return }

    print(mostRecentLocation.coordinate.latitude)
    print(mostRecentLocation.coordinate.longitude)

    Timer.scheduledTimer(
        timeInterval: 60.0,
        target: self,
        selector: #selector(StartTestVC.sendDataToServer(timer:)),
        userInfo: SendDataToServerData(mostRecentLocation: mostRecentLocation),
        repeats: true
    )
}

// Only to be called by the timer
func sendDataToServerTimerFunc(timer: Timer) {
    let mostRecentLocation = timer.userInfo as! SendDataToServerData
    self.sendDataToServer(
        latitude: mostRecentLocation.latitude
        longitude: mostRecentLocation.longitude
    )
}

// Call this function for all other uses
func sendDataToServer(latitude: Double, longitude: Double) {
    SFUserManager.shared.uploadPULocation(latitude, longitude:longitude)
}

sendDataToServer 每秒被调用一次,即使我设置了1秒。为什么? - pmb
@pmb 嗯?你打错字了吗? - Alexander
@pmb 当然不是,我没有重建整个项目只是为了运行这个。 - Alexander
这是我的错误,我在位置更新中调用了选择器,所以它没有起作用。抱歉啊兄弟。 - pmb
让我们在聊天中继续这个讨论 - Alexander
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接