• Swift Timer引起循环引用 2018-10-17 16:39:12
    当我们写一下代码会发现,deinit不会调用。 class ViewController: UIViewController { ... var timer:Timer? override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading ...

    当我们写一下代码会发现,deinit不会调用。

    class ViewController: UIViewController {
    
        var timer:Timer?
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view, typically from a nib.
            timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(abc), userInfo: nil, repeats: true)
            
        }
        
        deinit {
            timer?.invalidate()
            timer = nil
        }
    
        @objc func abc()  {
            
        }
    
    }

    这个因为,vc持有timer,timer也持有vc,引起循环引用。

    解决以上问题可以在适当的地方解除强引用,也可以不相互持。

    不相互持有可以在target中传入另一个对象。

    当然这样做很麻烦,因为每次用timer的时候都必须引入另一个对象。

    可以用runtime解决“另一个对象问题”

    class SecViewController: UIViewController {
    
        var timer:Timer?
        var blockTimer:Timer?
        override func viewDidLoad() {
            super.viewDidLoad()
    
            timer = Timer.hl_scheduledTimer(timeInterval: 1, target: self, selector: #selector(test), userInfo: nil, repeats: true)
            
            blockTimer = Timer.hl_scheduledTimer(withTimeInterval: 1, mode: .default, repeats: true, block: {
                
                print("blockTimer run")
                
            })
            
            
            // Do any additional setup after loading the view.
        }
        
        @objc func test()  {
            print("timer run")
        }
        
        deinit {
            timer?.invalidate()
            timer = nil
            blockTimer?.invalidate()
            blockTimer = nil
        }
        
    
    }

    我封装了2个方法,它们可以像以前Timer方法那样传参,但是不会引起循环引用。可以在deinit方法正常释放timer。

    hl_scheduledTimer(timeInterval:TimeInterval, target:Any, selector:Selector, userInfo:Any?, repeats:Bool)->Timer方法中引入了TimerTarget对象持有timer,在TimerTarget对象用runtime添加selector。

        @discardableResult //消除返回值警告
        public class func hl_scheduledTimer(timeInterval:TimeInterval, target:Any, selector:Selector, userInfo:Any?, repeats:Bool)->Timer{
            
            let t = TimerTarget()
            
            let imp = class_getMethodImplementation(object_getClass(target), selector)
            let method = class_getInstanceMethod(object_getClass(target), selector)
            let type = method_getTypeEncoding(method!)
            if let _ = class_getInstanceMethod(object_getClass(t), selector){
                
            }else{
                class_addMethod(object_getClass(t), selector, imp!, type)
            }
    
            return Timer.scheduledTimer(timeInterval: timeInterval, target: t, selector: selector, userInfo: userInfo, repeats: repeats)
            
        }

    hl_scheduledTimer(withTimeInterval: TimeInterval,mode:RunLoop.Mode = .default, repeats: Bool, block: @escaping () -> Void)->Timer方法是在Timer中添加一个属性持有block,当然也引入了TimerTarget对象。

    public class func hl_scheduledTimer(withTimeInterval: TimeInterval,mode:RunLoop.Mode = .default, repeats: Bool, block: @escaping () -> Void)->Timer{
            let t = TimerTarget()
            let timer = Timer(timeInterval: withTimeInterval, target: t, selector: #selector(TimerTarget.blockFunc(_:)), userInfo: nil, repeats: repeats)
            timer.hl_timerBlock = block
            RunLoop.main.add(timer, forMode: mode)
            return timer
        }

    timerDemo地址

    展开全文
  • 个人认为不是Timer和 控制器/视图 循环引用造成的释放不掉,而是timer对它的target是强引用造成的.为什么呢? 苹果提供的Timer是要添加到RunLoop上的,当前的RunLoop对定时器有一个强引用,而Tim...
  • Swift 3.0 解决Timer循环引用 2019-09-17 16:32:50
    今天封装一个无限轮播图,再次被Timer坑在了无限循环里。 在3.0中Timer的创建和使用是这样的 fileprivate var cycleTimer : Timer? cycleTimer = Timer(timeInterval: 3.0, targe...
  • 预防 Timer循环引用 2017.03.02 02:42* 字数 584 阅读 1098评论 0喜欢 1 在iOS开发过程中,Timer(NSTimer)是我们经常要使用的一个类。通过Timer,可以定时触发某个事件,或者执行一些特定的操作。但是稍微不...
  • 老问题,和OC写法差不多。用计时器发现deinit方法不走,页面有内存泄漏,而且计时器关不掉。 deinit { // 销毁计时器 ...简单说下问题点:self对自己的计时器属性timer引用timer设置target:self,
  •  15.9-解决闭包引起的循环引用问题  */    var cr: CycleRef? = CycleRef.init()  // 引用计数为1     // 我们知道延迟存储属性,第一次访问的时候才初始化。  cr!.closure()
  • Swift中的闭包 , 几乎和OC中的block... 在循环引用问题上 , 解决方案也更加简洁// HttpTool类 import UIKitclass HttpTool: NSObject { //闭包写法 : (参数列表) -> (返回值类型) func loadData(callBack:(jsonData:
  • Swift使用自动引用计数(ARC)来管理应用程序的内存使用。在大多是情况下,并不需要考虑内存的管理。当实例不再需要的时候,ARC会自动释放这些实例所使用的内存。 但ARC并不是绝对安全的。下面两种情况会发生内存...
  • Swift 安全的使用Timer 2019-10-14 00:08:02
    很多时候在Viewcontroller直接用属性引用Timer会造成引用循环timer会对target/vc进行强引用,vc对timer引用),下面的方式可以用Block的形式解除引用循环,避免内存泄漏。 // 破除timer引用循环 public type...
  • Swift 闭包中循环引用解决方式示例说明:开启一个定时器,然后每隔一秒钟加1秒,直到60秒变量声明//声明一个定时器变量 var timer: Timer? var currentSeconds: Int = 0 weak 方式 func testTimer(){ weak var ...
  • iOS NSTimer 的循环引用问题 2018-12-12 13:17:19
    话不多说直接上重点,先看 Timer 初始化: // // ViewController.swift // 计时器 // // Created by 张闯 on 2018/12/12. // Copyright © 2018 Rotai. All rights reserved. // import UIKit class ...
  • 在前文的基础上,还缺少timer的逻辑,在SwiftUI中可以通过接收publisher发出的事件。我们使用timer作为publisher,向视图发出事件,视图收到事件就可以做出响应 添加一个publisher的class类型 class TimePublisher {...
  • 相信大家在开发中都会使用到定时器, 但又常常对定时器的循环引用问题, NSTimer 释放时机的选择上,劳神费力! 读了本文,这些再也不是问题! 关于 NSTimer 创建定时器的方法,我就不多做描述了,网上很多例子,但...
  • 循环引用 2016-08-20 11:49:07
    循环引用指两个对象相互强引用了对方,即retain了对方,从而导致两个对象都无法被释放,引发了内存泄漏现象。在开发中很容易出现循环引用循环引用可能存在于代码的每个角落,会使内存消耗过高,性能变差,也可能会...
  • 当你在ViewController(简称VC)中使用timer属性,由于VC强引用timertimer的target又是VC造成循环引用。当你在VC的dealloc方法中销毁timer,发现VC被pop,VC的dealloc方法没走,VC在等timer释放才走dealloc,timer...
  • swift定时器的使用 2019-08-28 11:02:30
    Swift定时器的使用 在程序开发中,我们常常需要记录定时操作,比如短信验证码倒计时,运动计时等具有时间序列概念的操作。 最常用的定时方式有Timer 和GCD dispatchTimer 一、Timer的使用 Timer类的定义 主要...
  • Timer定时器 2017-08-04 15:19:54
    Timer定时器预防Timer循环引用,内存泄漏⚠️在iOS开发过程中,NSTimer 是我们经常要使用的类。但是稍不注意,就会导致内存泄漏,调用profile的Leaks工具时会发现MyViewController退出之后,就会检测到内存泄漏。...
  • Swift4 使用GCD实现计时器 2019-03-05 11:26:18
    开发过程中,我们可能会经常使用到计时器。苹果为我们提供了Timer。但是在平时使用过程中会发现使用Timer会有许多的不便 1:必须保证在一个活跃的runloop...可能循环引用造成内存泄露 由于存在上述问题,我们可以采...
  • 首先,说一下使用timer的误区,很多同学喜欢这样写:_timer = [NSTimer scheduledTimerWithTimeInterval:.5 target:self selector:@selector(timerRun:) userInf...
  • 免费下载地址:https://itunes.apple.com/cn/app/id1320746678◈ 不看视频不看书,手把手带您学习Swift语言◈ ...真正的Swift语言一点通,是您学习Swift语言的最佳方式【Swift4互动教程是什么】Swift4互动教程是一款简
1 2 3 4 5 ... 20
收藏数 507
精华内容 202