您的当前位置:首页正文

YYCache知识点

来源:华拓网

/**

A linked map used by YYMemoryCache.

It's not thread-safe and does not validate the parameters.

Typically, you should not use this class directly.

*/

@interface _YYLinkedMap : NSObject {
    @package
    CFMutableDictionaryRef _dic; // do not set object directly
    NSUInteger _totalCost;
    NSUInteger _totalCount;
    _YYLinkedMapNode *_head; // MRU, do not change it directly
    _YYLinkedMapNode *_tail; // LRU, do not change it directly
    BOOL _releaseOnMainThread;
    BOOL _releaseAsynchronously;
}

延迟执行:

void
dispatch_after(dispatch_time_t when,
    dispatch_queue_t queue,
    dispatch_block_t block);

时间相关

dispatch_time_t
dispatch_time(dispatch_time_t when, int64_t delta);
#define NSEC_PER_SEC 1000000000ull
#define USEC_PER_SEC 1000000ull
#define NSEC_PER_USEC 1000ull

NSEC:纳秒(nanosecond)
USEC:微秒(microsecond)
SEC:秒(second)
PER:每(percent)

    1   NSEC_PER_SEC,每秒有多少纳秒。
    2   USEC_PER_SEC,每秒有多少微秒。
    3   NSEC_PER_USEC,每微秒有多少纳秒。

NSDate 、CFAbsoluteTimeGetCurrent、CACurrentMediaTime 的差异

框架层:
NSDate 属于Foundation
CFAbsoluteTimeGetCurrent() 属于 CoreFoundatio
CACurrentMediaTime() 属于 QuartzCore
本质区别:
NSDate 或 CFAbsoluteTimeGetCurrent() 返回的时钟时间将会会网络时间同步,从时钟 偏移量的角度,mach_absolute_time() 和 CACurrentMediaTime() 是基于内建时钟的,能够更精确更原子化地测量,并且不会因为外部时间变化而变化(例如时区变化、夏时制、秒突变等),但它和系统的uptime有关,系统重启后CACurrentMediaTime()会被重置。

常见用法:
NSDate、CFAbsoluteTimeGetCurrent()常用于日常时间、时间戳的表示,与服务器之间的数据交互

其中 CFAbsoluteTimeGetCurrent() 相当于[[NSDate data] timeIntervalSinceReferenceDate];

CACurrentMediaTime() 常用于测试代码的效率


既然设置了ARC,为什么还要使用@autoreleasepool
用@autoreleasepool是有用的。

正常情况下,你创建的变量会在超出其作用域的时候被释放掉。

而如果你的函数写的很长,在你函数运行过程中出现很多中间变量,占据了大量的内存,怎么办?

用@autoreleasepool。


字符串格式化的深入理解了一点

    printf("NSDictionary:%8.2f\n", time * 1000);
    printf("NSDictionary:%15.2f\n", time * 1000);
    printf("NSDictionary:%8s\n", "abc");
    printf("NSDictionary:%15s\n", "abc");
    printf("NSDictionary:%15s\n", "abcdef");
    
    
    NSLog(@"NSDictionary:%8.2f\n", time * 1000);
    NSLog(@"NSDictionary:%15.2f\n", time * 1000);
    NSLog(@"NSDictionary:%8@\n", @"abc");
    NSLog(@"NSDictionary:%15@\n", @"abc");
    NSLog(@"NSDictionary:%15@\n", @"abcdef");

输出:

NSDictionary:   53.63
NSDictionary:          53.63
NSDictionary:     abc
NSDictionary:            abc
NSDictionary:         abcdef
2018-04-19 15:01:03.851864+0800 CacheBenchmark[4702:2623265] NSDictionary:   53.63
2018-04-19 15:01:03.851908+0800 CacheBenchmark[4702:2623265] NSDictionary:          53.63
2018-04-19 15:01:03.851933+0800 CacheBenchmark[4702:2623265] NSDictionary:     abc
2018-04-19 15:01:03.851944+0800 CacheBenchmark[4702:2623265] NSDictionary:            abc
2018-04-19 15:01:03.851953+0800 CacheBenchmark[4702:2623265] NSDictionary:         abcdef

define 宏定义的高级用法

#define INIT(...) self = super.init; \
if (!self) return nil; \
__VA_ARGS__; \
if (!_dic) return nil; \
_lock = OS_SPINLOCK_INIT; \
return self;

#define LOCK(...) OSSpinLockLock(&_lock); \
__VA_ARGS__; \
OSSpinLockUnlock(&_lock);


- (instancetype)init {
    INIT(_dic = [[NSMutableDictionary alloc] init]);
}

- (NSUInteger)count {
    LOCK(NSUInteger c = _dic.count); return c;
}



iOS 中生成随机数的4种方法(rand、random、arc4random、arc4random_uniform)

iOS 有如下四种随机数方法,下面以产生 [0,100) 的随机数为例:

1. srand((unsigned)time(0));  //不加这句每次产生的随机数不变
    int i = rand() % 100; 
2. srandom(time(0));
    int i = random() % 100;
3. int i = arc4random() % 100;
4. int i = arc4random_uniform(100)

异步到指定的队列中释放对象:

        _YYLinkedMapNode *node = [_lru removeTailNode];
        if (_lru->_releaseAsynchronously) {
            dispatch_queue_t queue = _lru->_releaseOnMainThread ? dispatch_get_main_queue() : YYMemoryCacheGetReleaseQueue();
            dispatch_async(queue, ^{
                [node class]; //hold and release in queue
            });
        } else if (_lru->_releaseOnMainThread && !pthread_main_np()) {
            dispatch_async(dispatch_get_main_queue(), ^{
                [node class]; //hold and release in queue
            });
        }

LRU算法 least recently used 算法
最少最近使用算法