我有一个在viewDidLoad
中运行的计时器_ = Timer.scheduledTimer(timeInterval: 10,
target: self,
selector: #selector(timerFired),
userInfo: nil,
repeats: true)
计时器工作正常,问题是因为多次调用viewDidLoad,计时器重复。
有没有办法确保我的计时器只运行一次?
答案 0 :(得分:3)
您需要保留对计时器的引用,以便在viewController消失时使其无效。否则它将继续运行,并且每次创建另一个viewController时都会生成新的计时器。
LDAP server: 10.10.1.2
LDAP server name: cz1.company.local
Realm: COMPANY.LOCAL
Bind Path: dc=COMPANY,dc=LOCAL
LDAP port: 389
Server time: Wed, 09 Nov 2016 16:46:09 CET
KDC server: 10.10.1.2
Server time offset: 0
Last machine account password change: Wed, 09 Nov 2016 16:34:20 CET
根据您的导航逻辑[2016/11/09 16:51:23.751082, 3] ../source3/auth/auth.c:178(auth_check_ntlm_password)
check_ntlm_password: Checking password for unmapped user [COMPANY]\[administrator]@[CZ2] with the new password interface
[2016/11/09 16:51:23.751106, 3] ../source3/auth/auth.c:181(auth_check_ntlm_password)
check_ntlm_password: mapped user is: [COMPANY]\[administrator]@[CZ2]
[2016/11/09 16:51:23.781423, 3] ../source3/auth/auth.c:249(auth_check_ntlm_password)
check_ntlm_password: winbind authentication for user [administrator] succeeded
[2016/11/09 16:51:23.781482, 2] ../source3/auth/auth.c:305(auth_check_ntlm_password)
check_ntlm_password: authentication for user [administrator] -> [administrator] -> [COMPANY/administrator] succeeded
[2016/11/09 16:51:23.781650, 3] ../auth/ntlmssp/ntlmssp_sign.c:509(ntlmssp_sign_reset)
NTLMSSP Sign/Seal - Initialising with flags:
[2016/11/09 16:51:23.781671, 3] ../auth/ntlmssp/ntlmssp_util.c:69(debug_ntlmssp_flags)
Got NTLMSSP neg_flags=0x62088215
[2016/11/09 16:51:23.781716, 3] ../auth/ntlmssp/ntlmssp_sign.c:509(ntlmssp_sign_reset)
NTLMSSP Sign/Seal - Initialising with flags:
[2016/11/09 16:51:23.781731, 3] ../auth/ntlmssp/ntlmssp_util.c:69(debug_ntlmssp_flags)
Got NTLMSSP neg_flags=0x62088215
[2016/11/09 16:51:23.783333, 1] ../source3/auth/token_util.c:430(add_local_groups)
SID S-1-5-21-2983937313-3188343367-1241514986-500 -> getpwuid(10500) failed
[2016/11/09 16:51:23.783370, 3] ../source3/auth/token_util.c:316(create_local_nt_token_from_info3)
Failed to finalize nt token
[2016/11/09 16:51:23.783395, 1] ../source3/smbd/sesssetup.c:290(reply_sesssetup_and_X_spnego)
Failed to generate session_info (user and group token) for session setup: NT_STATUS_UNSUCCESSFUL
[2016/11/09 16:51:23.783634, 3] ../source3/smbd/error.c:82(error_packet_set)
NT error packet at ../source3/smbd/sesssetup.c(293) cmd=115 (SMBsesssetupX) NT_STATUS_UNSUCCESSFUL
[2016/11/09 16:51:23.784947, 3] ../source3/smbd/server_exit.c:246(exit_server_common)
Server exit (failed to receive smb request)
[2016/11/09 16:51:23.817897, 3] ../source3/lib/util_procid.c:54(pid_to_procid)
pid_to_procid: messaging_dgm_get_unique failed: No such file or directory
可能会在取消分配视图之前多次调用,您必须自行决定处理此问题的最佳方法。
答案 1 :(得分:2)
viewDidLoad方法仅在视图控制器的生命周期内调用一次。
如果您运行多个计时器,那么您可能有多个视图控制器实例。否则,当您将视图控制器从导航堆栈中弹出并且计时器尝试再次调用它时,您可能会崩溃。
您需要通过释放它们来平衡您在viewDidLoad中创建的内容。
通常通过将清理代码放在deinit
方法中来平衡您在viewDidLoad中创建的内容。但是,它看起来像一个正在运行的计时器保持强烈引用它的目标。因此,如果你的视图控制器是一个运行计时器的目标,那么它的deinit方法就不会被调用。
我建议您在viewWillAppear中创建计时器并在viewWillDisappear中使其无效:
weak var timer: Timer?
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
timer = Timer.scheduledTimer(timeInterval: 1.0,
target: self,
selector: #selector(timerFired(timer:)),
userInfo: nil, repeats: true)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
timer?.invalidate()
}
或者,你可以使用带有块而不是目标/选择器的new-to-iOS 10版本的scheduledTimer()。 最终 Apple创建了此功能。关于d * amned time!
weak var timer: Timer?
override func viewDidLoad() {
super.viewDidLoad()
timer = Timer.scheduledTimer(withTimeInterval: 1.0,
repeats: true) {
[weak self] timer in
//Your timer code here
}
deinit {
timer?.invalidate()
}