GCD定时器封装OC&Swift

【Vue3 知识第六讲】ref、 shallowRef、unref、isRef 等系列知识应用 ref、 shallowRef、unref、isRef 等系列知识应用 阅读详情

前言

iOS开发中,经常需要使用到定时器,使用NSTimer很容易出现内存泄漏,在此简单封装GCD定时器。

作为一个开发者,有一个学习的氛围跟一个交流圈子特别重要,这是一个我的iOS交流群:812157648,不管你是小白还是大牛欢迎入驻 ,分享BAT,阿里面试题、面试经验,讨论技术, 大家一起交流学习成长!

OC版本

@interface CLGCDTimer ()

/**队列*/
@property (nonatomic, strong) dispatch_queue_t queue;
/**定时器*/
@property (nonatomic, strong) dispatch_source_t timer;
/**执行时间*/
@property (nonatomic, assign) NSTimeInterval interval;
/**延迟时间*/
@property (nonatomic, assign) NSTimeInterval delaySecs;
/**是否重复*/
@property (nonatomic, assign) BOOL repeat;
/**是否正在运行*/
@property (nonatomic, assign) BOOL isRuning;
/**响应次数*/
@property (nonatomic, assign) NSInteger actionTimes;
///名称
@property (nonatomic, copy) NSString *name;
/**响应*/
@property (nonatomic, copy) void (^action) (NSInteger actionTimes);

@end

@implementation CLGCDTimer

- (instancetype _Nonnull)initWithName:(NSString *)name
                             interval:(NSTimeInterval)interval
                            delaySecs:(NSTimeInterval)delaySecs
                                queue:(dispatch_queue_t _Nullable)queue
                              repeats:(BOOL)repeats
                               action:(void(^ _Nullable)(NSInteger actionTimes))action {
    CLGCDTimer *timer = [self initWithInterval:interval
                                     delaySecs:delaySecs
                                         queue:queue
                                       repeats:repeats
                                        action:action];
    timer.name = name;
    return timer;
}
- (instancetype _Nonnull)initWithInterval:(NSTimeInterval)interval
                                delaySecs:(NSTimeInterval)delaySecs
                                    queue:(dispatch_queue_t _Nullable)queue
                                  repeats:(BOOL)repeats
                                   action:( void(^ _Nullable)(NSInteger actionTimes))action {
    if (self = [super init]) {
        if (queue == nil) {
            queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        }
        self.interval = interval;
        self.delaySecs = delaySecs;
        self.repeat = repeats;
        self.action = action;
        self.isRuning = NO;
        self.queue = dispatch_queue_create([[NSString stringWithFormat:@"CLGCDTimer.%p", self] cStringUsingEncoding:NSASCIIStringEncoding], DISPATCH_QUEUE_SERIAL);
        self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, self.queue);
        dispatch_set_target_queue(self.queue, queue);
    }
    return self;
}
- (void)replaceOldAction:(void(^ _Nonnull)(NSInteger actionTimes))action {
    if (action) {
        self.action = action;
    }
}
/**开始定时器*/
- (void)start {
    dispatch_source_set_timer(self.timer, dispatch_time(DISPATCH_TIME_NOW, (NSInteger)(self.delaySecs * NSEC_PER_SEC)),(NSInteger)(self.interval * NSEC_PER_SEC), 0 * NSEC_PER_SEC);
    __weak __typeof(self) weakSelf = self;
    dispatch_source_set_event_handler(self.timer, ^{
        __typeof(&*weakSelf) strongSelf = weakSelf;
        strongSelf.actionTimes ++;
        if (strongSelf.action) {
            strongSelf.action(strongSelf.actionTimes);
        }
        if (!strongSelf.repeat) {
            [strongSelf cancel];
        }
    });
    [self resume];
}
/**执行一次定时器响应*/
- (void)responseOnce {
    self.actionTimes ++;
    self.isRuning = YES;
    if (self.action) {
        self.action(self.actionTimes);
    }
    self.isRuning = NO;
}
/**取消定时器*/
- (void)cancel {
    if (!self.isRuning) {
        [self resume];
    }
    dispatch_source_cancel(self.timer);
}
/**暂停定时器*/
- (void)suspend {
    if (self.isRuning) {
        dispatch_suspend(self.timer);
        self.isRuning = NO;
    }
}
/**恢复定时器*/
- (void)resume {
    if (!self.isRuning) {
        dispatch_resume(self.timer);
        self.isRuning = YES;
    }
}
-(void)dealloc {
    [self cancel];
}

@end

@interface CLGCDTimerManager ()

/**CLGCDTimer字典*/
@property (nonatomic, strong) NSMutableDictionary *timerObjectCache;
/**信号*/
@property (nonatomic, strong) dispatch_semaphore_t semaphore;

@end

@implementation CLGCDTimerManager

#pragma mark - 初始化
//第1步: 存储唯一实例
static CLGCDTimerManager *_manager = nil;
//第2步: 分配内存空间时都会调用这个方法. 保证分配内存alloc时都相同.
+ (id)allocWithZone:(struct _NSZone *)zone {
    //调用dispatch_once保证在多线程中也只被实例化一次
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _manager = [super allocWithZone:zone];
    });
    return _manager;
}
//第3步: 保证init初始化时都相同
+ (instancetype)sharedManager {
    return [[self alloc] init];
}
- (id)init {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _manager = [super init];
        self.timerObjectCache = [NSMutableDictionary dictionary];
        self.semaphore = dispatch_semaphore_create(0);
        dispatch_semaphore_signal(self.semaphore);
    });
    return _manager;
}
//第4步: 保证copy时都相同
- (id)copyWithZone:(NSZone __unused*)zone {
    return _manager;
}
//第五步: 保证mutableCopy时相同
- (id)mutableCopyWithZone:(NSZone __unused*)zone {
    return _manager;
}
//MARK:JmoVxia---创建定时器
+ (void)scheduledTimerWithName:( NSString * _Nonnull)name
                      interval:(NSTimeInterval)interval
                     delaySecs:(NSTimeInterval)delaySecs
                         queue:(dispatch_queue_t _Nullable)queue
                       repeats:(BOOL)repeats
                        action:(void(^ _Nullable)(NSInteger actionTimes))action {
    __strong NSString *string = name;
    CLGCDTimer *GCDTimer = [self timer:string];
    if (GCDTimer) {
        return;
    }
    GCDTimer = [[CLGCDTimer alloc] initWithName:string
                                       interval:interval
                                      delaySecs:delaySecs
                                          queue:queue
                                        repeats:repeats
                                         action:action];
    [self setTimer:GCDTimer name:string];
}
//MARK:JmoVxia---开始定时器
+ (void)start:(NSString *_Nonnull)name {
    __strong NSString *string = name;
    CLGCDTimer *GCDTimer = [self timer:string];
    if (GCDTimer) {
        [GCDTimer start];
    }
}
//MARK:JmoVxia---执行一次定时器响应
+ (void)responseOnce:(NSString *_Nonnull)name {
    __strong NSString *string = name;
    CLGCDTimer *GCDTimer = [self timer:string];
    if (GCDTimer) {
        [GCDTimer responseOnce];
    }
}
//MARK:JmoVxia---取消定时器
+ (void)cancel:(NSString *_Nonnull)name {
    __strong NSString *string = name;
    CLGCDTimer *GCDTimer = [self timer:string];
    if (GCDTimer) {
        [GCDTimer cancel];
        [self removeTimer:name];
    }
}
//MARK:JmoVxia---暂停定时器
+ (void)suspend:(NSString *_Nonnull)name {
    __strong NSString *string = name;
    CLGCDTimer *GCDTimer = [self timer:string];
    if (GCDTimer) {
        [GCDTimer suspend];
    }
}
//MARK:JmoVxia---恢复定时器
+ (void)resume:(NSString *_Nonnull)name {
    __strong NSString *string = name;
    CLGCDTimer *GCDTimer = [self timer:string];
    if (GCDTimer) {
        [GCDTimer resume];
    }
}
//MARK:JmoVxia---获取定时器
+ (CLGCDTimer *_Nullable)timer:(NSString *_Nonnull)name {
    dispatch_semaphore_wait([CLGCDTimerManager sharedManager].semaphore, DISPATCH_TIME_FOREVER);
    __strong NSString *string = name;
    CLGCDTimer *GCDTimer = [[CLGCDTimerManager sharedManager].timerObjectCache objectForKey:string];
    dispatch_semaphore_signal([CLGCDTimerManager sharedManager].semaphore);
    return GCDTimer;
}
//MARK:JmoVxia---储存定时器
+ (void)setTimer:(CLGCDTimer *_Nonnull)timer name:(NSString *_Nonnull)name {
    dispatch_semaphore_wait([CLGCDTimerManager sharedManager].semaphore, DISPATCH_TIME_FOREVER);
    [[CLGCDTimerManager sharedManager].timerObjectCache setObject:timer forKey:name];
    dispatch_semaphore_signal([CLGCDTimerManager sharedManager].semaphore);
}
//MARK:JmoVxia---移除定时器
+ (void)removeTimer:(NSString *_Nonnull)name {
    dispatch_semaphore_wait([CLGCDTimerManager sharedManager].semaphore, DISPATCH_TIME_FOREVER);
    [[CLGCDTimerManager sharedManager].timerObjectCache removeObjectForKey:name];
    dispatch_semaphore_signal([CLGCDTimerManager sharedManager].semaphore);
}
@end

Swift版本

class CLGCDTimer: NSObject {
    
    typealias actionBlock = ((NSInteger) -> Void)

    ///执行时间
    private var interval: TimeInterval!
    ///延迟时间
    private var delaySecs: TimeInterval!
    ///队列
    private var serialQueue: DispatchQueue!
    ///是否重复
    private var repeats: Bool = true
    ///响应
    private var action: actionBlock?
    ///定时器
    private var timer: DispatchSourceTimer!
    ///是否正在运行
    private var isRuning: Bool = false
    ///响应次数
    private (set) var actionTimes: NSInteger = 0
    
    /// 创建定时器
    ///
    /// - Parameters:
    ///   - interval: 间隔时间
    ///   - delaySecs: 第一次执行延迟时间,默认为0
    ///   - queue: 定时器调用的队列,默认子队列
    ///   - repeats: 是否重复执行,默认true
    ///   - action: 响应
    init(interval: TimeInterval, delaySecs: TimeInterval = 0, queue: DispatchQueue = DispatchQueue.global(), repeats: Bool = true, action:  actionBlock?) {
        super.init()
        self.interval = interval
        self.delaySecs = delaySecs
        self.serialQueue = DispatchQueue.init(label: String(format: "CLGCDTimer.%p", self), target: queue)
        self.action = action
        self.timer = DispatchSource.makeTimerSource(queue: self.serialQueue)
    }
    ///替换旧响应
    func replaceOldAction(action: actionBlock?) -> Void {
        guard let action = action else {
            return
        }
        self.action = action
    }
    ///执行一次定时器响应
    func responseOnce() {
        actionTimes += 1
        isRuning = true
        action?(actionTimes)
        isRuning = false
    }
    deinit {
        cancel()
    }
}

extension CLGCDTimer {
    ///开始定时器
    func start() {
        timer.schedule(deadline: .now() + delaySecs, repeating: interval, leeway: DispatchTimeInterval.never)
        timer.setEventHandler { [weak self] in
            guard let strongSelf = self else {
                return
            }
            strongSelf.actionTimes += 1
            strongSelf.action?(strongSelf.actionTimes)
            if !strongSelf.repeats {
                strongSelf.cancel()
            }
        }
        resume()
    }
    ///暂停
    func suspend() {
        if isRuning {
            timer.suspend()
            isRuning = false
        }
    }
    ///恢复定时器
    func resume() {
        if !isRuning {
            timer.resume()
            isRuning = true;
        }
    }
    ///取消定时器
    func cancel() {
        if !isRuning {
            resume()
        }
        timer.cancel()
    }
}

class CLGCDTimerManager: NSObject {
    
    typealias actionBlock = ((NSInteger) -> Void)
    
    private static let sharedManager: CLGCDTimerManager = CLGCDTimerManager()
    private var timerObjectCache: Dictionary<String, CLGCDTimer> = Dictionary()
    private let semaphore: DispatchSemaphore = DispatchSemaphore(value: 0)
    private override init() {
       semaphore.signal()
    }
    
    /// 创建全局定时器
    ///
    /// - Parameters:
    ///   - name: 定时器名称
    ///   - interval: 间隔时间
    ///   - delaySecs: 第一次执行延迟时间,默认为0
    ///   - queue: 定时器调用的队列,默认子队列
    ///   - repeats: 是否重复执行,默认true
    ///   - action: 响应
    class func scheduledTimer(name: String, interval: TimeInterval, delaySecs: TimeInterval = 0, queue: DispatchQueue = DispatchQueue.global(), repeats: Bool = true, action:  actionBlock?) {
        var GCDTimer: CLGCDTimer? = timer(name)
        if (GCDTimer != nil) {
            return
        }
        GCDTimer = CLGCDTimer(interval: interval, delaySecs: delaySecs, queue: queue, repeats: repeats, action: action)
        setTimer(GCDTimer!, name)
    }
}
extension CLGCDTimerManager {
    ///开始定时器
    class func start(_ name: String) {
        let GCDTimer: CLGCDTimer? = timer(name)
        GCDTimer?.start()
    }
    ///执行一次定时器
    class func responseOnce(_ name: String) {
        let GCDTimer: CLGCDTimer? = timer(name)
        GCDTimer?.responseOnce()
    }
    ///取消定时器
    class func cancel(_ name: String) {
        let GCDTimer: CLGCDTimer? = timer(name)
        guard let timer = GCDTimer else {
            return
        }
        timer.cancel()
        removeTimer(name)
    }
    ///暂停定时器
    class func suspend(_ name: String) {
        let GCDTimer: CLGCDTimer? = timer(name)
        GCDTimer?.suspend()
    }
    ///恢复定时器
    class func resume(_ name: String) {
        let GCDTimer: CLGCDTimer? = timer(name)
        GCDTimer?.resume()
    }
}
extension CLGCDTimerManager {
    private class func timer(_ name: String) -> CLGCDTimer? {
        sharedManager.semaphore.wait()
        let GCDTimer = sharedManager.timerObjectCache[name]
        sharedManager.semaphore.signal()
        return GCDTimer
    }
    private class func setTimer(_ timer: CLGCDTimer, _ name: String) {
        sharedManager.semaphore.wait()
        sharedManager.timerObjectCache.updateValue(timer, forKey: name)
        sharedManager.semaphore.signal()
    }
    private class func removeTimer(_ name: String) {
        sharedManager.semaphore.wait()
        sharedManager.timerObjectCache.removeValue(forKey: name)
        sharedManager.semaphore.signal()
    }
}

其他
简单的封装了一下,仅供大家参考,代码比较简单,完整项目地址------>CLDemo

原文作者:季末微夏
原文地址:https://www.jianshu.com/p/6ce61ccca31a

javascript中setTimeout和setInterval的unref()和ref()用法示例 unref()和ref()用法非常的简单,就是取消和回复setTimeout和setInterval函數的調用的。 代码如下: 代码如下:  var testFunction=function(){      console.log(“guoyansi”);  }  var timer=setInterval(testFunction,1000);  timer.unref();//取消setTimeout和setInterval函數的調用  timer.ref();//恢復setTimeout和setInterval函數的調用 是不是超级简单,如果还不明白,请放过javascript吧 立即下载

相关推荐

新手别怕!用‘东北天’和‘右前上’坐标系,5分钟搞懂惯性导航姿态矩阵(含Python验证代码)

本文通过‘东北天(ENU)’和‘右前上(RFU)’坐标系,详细解析惯性导航中的姿态矩阵概念。包含Python代码验证,帮助新手快速理解坐标变换、欧拉角及旋转矩阵的构建与应用,特别强调有限转动不可交换性与无限转动次序无关的区别。

weixin_29062255的博客 332

【Vue3】 中的 【unref】:详解与使用

vue unref

jhgj56的博客 2380

【强化学习】常用算法之一 “A3C”

A3C(Asynchronous Advantage Actor-Critic)算法是一种在强化学习领域中应用广泛的算法,它结合了策略梯度方法和价值函数的学习,用于近似解决马尔可夫决策过程(Markov Decision Process)问题。A3C算法在近年来备受关注,因为它在处理大规模连续动作空间和高维状态空间方面具有出色的性能。A3C算法是一种基于策略梯度的强化学习算法,通过多个并行的智能体异步地与环境交互,并利用Actor和Critic网络实现策略和价值的近似,从而实现快速而稳定的强化学习训练。

Code_and516的博客 6756

Vue3.0 reactive()、ref()、unref()、isref()、toRefs()、computed()

reactive() 等价于 vue 2.x 中的 Vue.observable() 函数,vue 3.x 中提供了 reactive() 函数,用来创建 响应式的数据对象。 当(引用)数据 直接改变 不会让模版响应 更新渲染: 一秒后页面没有变化 <template> <div>count: {{state.count}}</div> </template> <script> export default { setup() {

qq_095的博客 4万+

[小梅哥FPGA] 如何通过动态重配置实现FPGA时钟的实时频率/相位/占空比调整?

PLL和MMCM是实际存在的硬件电路,用以对输入时钟的负面变化,如抖动、频率变化、相位偏移、占空比失真等进行处理。基于该表,用户在初始化Clk_Wiz后,只需要计算好所需的频率、相位、占空比对应的设置值,使用Xil_Out32函数配置对应寄存器即可。通过上述步骤,在平时的开发调试过程中,亦或是一些对于时钟可能有着实时性要求的设计(如数据采集、图像处理)里,我们便可以在无需重新修改设计的前提下,通过AXI4总线来完成对时钟频率、相位的调控,从而达到缩短设计周期以及让设计适应更多场景的目的。

zgmxs的专栏 2493

Verilog中generate for循环的5个实战技巧(附完整代码示例)

本文详细介绍了Verilog中generate for循环的5个高级实战技巧,包括参数化模块实例化、条件化生成、多维硬件结构实现等,并附有完整代码示例。这些技巧能显著提升FPGA开发效率,特别适合中级Verilog开发者学习应用。

weixin_28725949的博客 187

Vue3:可以使用.value获取ref()包裹的值,为何还要存在unref()

本文将介绍 unref() 函数的示例,以及回答为什么可以使用.value获取ref()包裹的值,还要存在unref()。

yyyyyyyyyyy_9的博客 2827

RV1126B SDK移植实战:从DDR配置到USB烧写全解析

本文详细解析了RV1126B SDK移植的核心实战流程,重点攻克了DDR初始化失败与USB烧写两大难题。文章从理解启动流程入手,提供了DDR配置错误的排查步骤、SDK编译配置要点,并深入讲解了USB烧写的完整操作与常见问题解决方案,旨在帮助开发者高效完成系统移植与稳定运行。

weixin_29164497的博客 542

Vue3.0 ref()、isRef()、unref()、reactive()、toRefs()、computed()

1.ref() 定义一个响应式的数据 但是获取的时候要 .value 才能获取定义的值 2.isRef() 判断一个值是否为一个 ref 对象。 3.unref() 如果参数是一个 ref 则返回它的 value,否则返回参数本身。 unref():是 val = isRef(val) ? val.value : val 的语法糖。 4.reactive() 函数,用来创建 响应式的数据对象。 当需要大量数据的时候reactive()是一个很好的选择,不需要重复声明。 定义

weixin_57811717的博客 2041

innovus:sroute 双层follow pin的做法

根据std cellpower pin的层次可以分成两种情况。

m0_61544122的博客 2726

RK3568平台(网络篇)WIFI模块RTL8821CU调试

RTL8821CU是瑞昱半导体推出的usb接口的wifi,下面的教程将介绍如何将RTL8821CU移植到rk3588的平台上。移植usb wifi需要修改的文件Android hal层需要修改的文件//kernel需要修改的文件kernel/arch/arm64/boot/dts/rockchip/rk3399-tve1030g.dtsi //除去板上的sdio的wifi。

weixin_49303682的博客 3904

Node.js定时器中的ref函数和unref函数

Javascript中有两大和定时有关的函数,setTimeout和setInterval。这两个方法都是在设定的事件之后,把回调函数放入调用栈的最后,一个是只执行一次,一个是重复执行。(这篇文章的重点不是讲这两个,有疑问的同学请自行搜索资料) 清除这两个定时操作是把定时器传入clearTimeout和clearInterval函数。这两个函数的操作也非常清晰。 上述的内容在浏览器和Node.js中都可以使用。 但是还有两个函数,ref()和unref(),这两个操作也是和清楚定时器有关,但是性.

Coding home - 漂流瓶jz 3569

华为OD机试 新系统 双机位C卷 往年真题 机考题库(持续收录中)以及算法考点详解(Python/JS/C/C++)

刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释发现新题目,随时更新。

学Java,找哪吒 5万+

TimerQueueTimer使用问题总结

因为项目原因,需要处理socket连接超时资源释放问题        原来使用单个线程轮训,效率较低,后改为TimerQueue,参考文档http://blog.youkuaiyun.com/querw/article/details/6600327        官方的帮助文档: http://msdn.microsoft.com/zh-cn/office/ms687003(v=vs.85)很简略

tpriwwq的专栏 8769

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

isRef、unRef、toRef、toRefs、shallowRef、triggerRef

toRefs是把一个响应式对象变成普通对象,这个对象每个属性都指向源对象相应属性的ref;toRef可以把一个响应式对象的属性也变成响应式,这样创建的ref与其源属性保持一致;unRef是一个语法糖,如果参数是ref,返回它的内部值,否则返回它本身,相当于。isRef检查某个值是否是ref;

content6的博客 730

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

Vue3中,ref、toRef、toRefs、isRef、unref

Vue3响应式工具函数对比:ref创建独立响应式变量,通过.value访问;toRef将对象属性转为ref并保持连接;toRefs用于解构响应式对象时保持响应性;isRef检查值是否为ref;unref安全获取ref值。这些函数各有适用场景,合理使用可提升状态管理效率,保持代码简洁性和可维护性。注意模板自动解包特性和性能考虑,在表单处理、组合式函数等场景中尤为实用。

油墨香^-^的博客 8249

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

[深入vue3之refs] ref、unref、toRef、toRefs、isRef、customRef、shallowRef、triggerRef等使用与讲解

【代码】[深入vue3之refs] ref、unref、toRef、toRefs、isRef、customRef、shallowRef、triggerRef等使用与讲解。

DTCloud 1527

vue3 ref 、unref 、toRef、toRefs

vue3 ref 、unref 、toRef、toRefs 的使用

fggfgf的博客 1万+

nodejs ref操作_nodejs事件和事件循环详解

简介上篇文章我们简单的介绍了nodejs中的事件event和事件循环event loop。本文本文将会更进一步,继续讲解nodejs中的event,并探讨一下setTimeout,setImmediate和process.nextTick的区别。nodejs中的事件循环虽然nodejs是单线程的,但是nodejs可以将操作委托给系统内核,系统内核在后台处理这些任务,当任务完成之后,通知nodejs...

weixin_34634231的博客 895

net4. 定时器类——TimerId、Timer、TimerQueue

定时器类图 TimerId:用户只能看到这个类,是一个不透明的类,cancel()函数用这个类来取消定时器 Timer:对定时操作进行抽象的定时器类 TimerQueue:定时器队列 时序图: 1.TimerId类 数据成员: Timer* timer_:定时器timer_ int64_t sequence_:定时器的序号,每个定时器都有唯一的一个编号 成员函数: TimerId():构造函数 TimerId(Timer* timer, int64_t seq):构造函数 TimerId.h #ifnd

TABE_的博客 1217

Vue isRef、unref、toRef和toRefs的用法

如果参数是ref,则返回內部值,否则返回参数本身基于响应式对象上的一个属性,创建一个对应的ref,这样创建的ref与其源属性保持同步,改变源属性的值将更新ref的值,反之亦然将一个响应式对象转换为一个普通对象,这个普通对象的每个属性都是指向源对象相应属性的ref,每个单独的ref都是用toRef()创建的。

g841805的博客 1324

Muduo分析及总结(一)定时器(TimerQueue、TimerId、Timer)

类关系图 TimerId :表示一个定时器的整体,有定时器和序列号。 Timer:就是一个定时器的封装。 TimerQueue:定时器的处理流程封装。 时序图 定时器的使用 TimeQueue被封装在EventLoop中,定时器的使用要通过EventLoop /在时间戳为time的时间执行,0.0表示一次性不重复 TimerId EventLoop::runAt(const Timestamp...

蜗牛,为梦想而生。 2161

vue3基础-响应式 API 之 unref、toRef、toRefs、isRef

unref 如果参数是一个 ref,则返回内部值,否则返回参数本身。 toRef 将对象的某个属性转为响应式,修改值时原始值也会改变,但是值改变不会更新视图 使用示例: <template> <div class="home"> <div>{{userInfo.name}}</div> <div>{{userInfo.age}}</div> <button @click="changeUserN

龙衣 2009

ref/unref应该返回什么值

ref/unref应该返回什么值 转载时请注明出处和作者联系方式作者联系方式:李先静 引用计数是追踪对象生命周期最常用的方法,一方面保证对象在有人使用时不会被销毁,另外一方面又保证不会因为忘记销毁对象而造成内存泄漏。具有引用计数功能的对象一般都会提供两个函数:ref用于增加引用计数,unref用于减少引用计数,计数为0时销毁对象。 一个有趣的问题是,这两个函数应该返回什么值呢?我们

国产开源 GUI 引擎 AWTK 4100
上一篇: 自定义UITextView输入框
下一篇: iOS加密之AES128-NoPadding-CBC
iOS发呆君
博客等级 码龄6年 8粉丝 41原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值