美文网首页
YYMemoryCache笔记

YYMemoryCache笔记

作者: Theodore_Pratt | 来源:发表于2018-07-12 17:34 被阅读27次

    友情提醒:这篇文章不是解析YYMemoryCache源码,只是个人解读源码时学到的一些东西做下笔记,希望也能帮到你,如果是要看源码解读的朋友们可以移步其他文章了哈~

    1. nonnull宏定义

    给两个宏之间的变量自动添加nonnull修饰,如果需要个别nullable则单独标出,非常方便。

    NS_ASSUME_NONNULL_BEGIN 
    // 中间的变量会自动添加nonnull修饰,避免繁琐的添加
    NS_ASSUME_NONNULL_END
    
    2.inline内链函数

    inline定义的类的内联函数,函数的代码被放入符号表中,在使用时直接进行替换,(像宏一样展开),没有了调用的开销,效率也很高。

    // 频繁获取异步线程,使用内链函数避免调用开销
    static inline dispatch_queue_t YYMemoryCacheGetReleaseQueue() {
        return dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);
    }
    
    3.异步释放资源:调用类的方法进行异步释放

    holder为一个数组,直接调用数组的count方法,进行异步资源释放。

    dispatch_async(queue, ^{
        [holder count]; // release in queue
    });
    
    4.用互斥锁实现自旋锁逻辑
    pthread_mutex_t _lock; // 声明
    pthread_mutex_init(&_lock, NULL); // 初始化锁
    pthread_mutex_lock(&_lock); // 加锁
    pthread_mutex_trylock(&_lock) // 获取并加锁(返回值为0为成功)
    pthread_mutex_unlock(&_lock); // 解锁
    pthread_mutex_destroy(&_lock); // 释放锁
    

    使用pthread_mutex_trylock获取线程锁,如果得到锁,进行相关逻辑,如果锁忙,则等待10ms(避免短时间大量循环占用资源)。

    OSSpinLock线程不安全之后替换的逻辑

    NSMutableArray *holder = [NSMutableArray new];
    while (!finish) {
        if (pthread_mutex_trylock(&_lock) == 0) {
            if (_lru->_tail && (now - _lru->_tail->_time) > ageLimit) {
                _YYLinkedMapNode *node = [_lru removeTailNode];
                if (node) [holder addObject:node];
            } else {
                 finish = YES;
            }
            pthread_mutex_unlock(&_lock);
        } else {
                usleep(10 * 1000); //10 ms
        }
    }
    
    5.CACurrentMediaTime() 函数

    可参考Mattt的文章Benchmarking,主要用来测试代码效率。

    NSDateCFAbsoluteTimeGetCurrent()偏移量不同的是,mach_absolute_time()CACurrentMediaTime()是基于内建时钟的,能够更精确更原子化地测量,并且不会因为外部时间变化而变化(例如时区变化、夏时制、秒突变等)

    另外引用一下Mattt使用dispatch_benchmark测试代码效率的使用实例:

    static size_t const count = 1000;
    static size_t const iterations = 10000;
    id object = @"🐷";
    // 声明benchmark
    extern uint64_t dispatch_benchmark(size_t count, void (^block)(void));
    // 使用benchmark
    uint64_t t = dispatch_benchmark(iterations, ^{
        @autoreleasepool {
            NSMutableArray *mutableArray = [NSMutableArray array];
            for (size_t i = 0; i < count; i++) {
                [mutableArray addObject:object];
            }
        }
    });
    NSLog(@"[[NSMutableArray array] addObject:] Avg. Runtime: %llu ns", t);
    
    6.pthread_main_np() 函数

    判断是否是主线程使用,返回值为1时为主线程

    还有[NSThread currentThread]

    相关文章

      网友评论

          本文标题:YYMemoryCache笔记

          本文链接:https://www.haomeiwen.com/subject/iuvaettx.html