Swift中Timer计时器循环引用问题
2017-08-22 11:58
946 查看
老问题,和OC写法差不多。用计时器发现deinit方法不走,页面有内存泄漏,而且计时器关不掉。
deinit {
// 销毁计时器
timer?.invalidate();
}可以在特定节点主动调用
简单说下问题点:self对自己的计时器属性timer强引用,timer设置target:self,并且是循环操作计时器(repeats:true),timer对self也是强引用,循环引用了。deinit就不执行。
方案:timer扩展方法,将要执行的操作,就是selector(...),以block的形式传入userinfo中,以此打破循环。
//
// Timer+Extensions.swift
// MPPForSwift
//
// Created by meipaipai on 2017/8/22.
// Copyright © 2017年 liyinkai. All rights reserved.
//
import Foundation
extension Timer {
class func lyk_scheduledTimer (timeInterval: TimeInterval, repeats: Bool, completion:((_ timer:Timer)->())) -> Timer{
return Timer.scheduledTimer(timeInterval: timeInterval, target: self, selector: #selector(lyk_completionLoop(timer:)),
userInfo: completion, repeats: repeats);
}
@objc class func lyk_completionLoop(timer:Timer) {
guard let completion = timer.userInfo as? ((Timer) -> ()) else {
return;
}
completion(timer);
}
}以上代码是给timer扩展两个类方法
// MARK: - 计时器相关方法
extension LYKVerificationCodeViewController {
/// 创建计时器
fileprivate func setupTimer () {
timer = Timer.lyk_scheduledTimer(timeInterval: 1.0, repeats: true, completion: { [weak self](timer) in
guard let strongSelf = self else {
return;
}
strongSelf.timerFunc();
});
}
/// 计时器实现方法
fileprivate func timerFunc () {
sixtySecond = sixtySecond - 1;
print(sixtySecond);
countDownLabel.text = "接收短信大概需要\(sixtySecond)秒钟";
if sixtySecond == 0 {
// 暂时计时器,重置 60 秒计时时间
timer?.fireDate = Date.distantFuture;
sixtySecond = 60;
// 显示重新发送按钮
countDownLabel.isHidden = true;
resendButton.isHidden = false;
}
}
}以上代码是操作计时器代码。基本和OC的逻辑差不多。
值得一说的点,[weak self],相当于OC的__weak。写了这个,block中所有的self都是弱引用了(是比OC方便点。。。)。
deinit {
// 销毁计时器
timer?.invalidate();
}可以在特定节点主动调用
timer?.invalidate();但是并不完美~~
简单说下问题点:self对自己的计时器属性timer强引用,timer设置target:self,并且是循环操作计时器(repeats:true),timer对self也是强引用,循环引用了。deinit就不执行。
方案:timer扩展方法,将要执行的操作,就是selector(...),以block的形式传入userinfo中,以此打破循环。
//
// Timer+Extensions.swift
// MPPForSwift
//
// Created by meipaipai on 2017/8/22.
// Copyright © 2017年 liyinkai. All rights reserved.
//
import Foundation
extension Timer {
class func lyk_scheduledTimer (timeInterval: TimeInterval, repeats: Bool, completion:((_ timer:Timer)->())) -> Timer{
return Timer.scheduledTimer(timeInterval: timeInterval, target: self, selector: #selector(lyk_completionLoop(timer:)),
userInfo: completion, repeats: repeats);
}
@objc class func lyk_completionLoop(timer:Timer) {
guard let completion = timer.userInfo as? ((Timer) -> ()) else {
return;
}
completion(timer);
}
}以上代码是给timer扩展两个类方法
// MARK: - 计时器相关方法
extension LYKVerificationCodeViewController {
/// 创建计时器
fileprivate func setupTimer () {
timer = Timer.lyk_scheduledTimer(timeInterval: 1.0, repeats: true, completion: { [weak self](timer) in
guard let strongSelf = self else {
return;
}
strongSelf.timerFunc();
});
}
/// 计时器实现方法
fileprivate func timerFunc () {
sixtySecond = sixtySecond - 1;
print(sixtySecond);
countDownLabel.text = "接收短信大概需要\(sixtySecond)秒钟";
if sixtySecond == 0 {
// 暂时计时器,重置 60 秒计时时间
timer?.fireDate = Date.distantFuture;
sixtySecond = 60;
// 显示重新发送按钮
countDownLabel.isHidden = true;
resendButton.isHidden = false;
}
}
}以上代码是操作计时器代码。基本和OC的逻辑差不多。
值得一说的点,[weak self],相当于OC的__weak。写了这个,block中所有的self都是弱引用了(是比OC方便点。。。)。
相关文章推荐
- Swift 解决循环引用问题
- OC和Swift中循环引用的问题
- 小胖说swift07-------- swift协议代理的使用以及解决循环引用问题
- Swift 内存管理与循环引用问题(weak、unowned)
- Swift:(十一)、构造器、自动引用计数、循环引用问题解决、类型转换
- swift - 循环引用问题
- 解决swift中闭包中循环引用self 的问题
- swift协议代理的使用以及解决循环引用问题
- Swift自定义数据模型及闭包的循环引用问题
- swift闭包中解决循环引用的问题
- swift protocol 协议代理的使用以及解决循环引用问题
- 15.8 Swift闭包属性引起的循环强引用问题
- swift之闭包循环引用问题及解决方式
- 15.9 Swift解决闭包引起的循环强引用问题
- 最近在使用swift写代码时碰到block引用循环的问题。记下一笔以免忘记。
- swift中关于代理的循环引用问题
- Block循环引用问题
- Spring boot (21)多数据源引起的循环引用和AutoConfigureAfter失效的问题
- ios block循环引用问题
- 循环引用问题