友情提醒:這篇文章不是解析YYMemoryCache源碼,只是個(gè)人解讀源碼時(shí)學(xué)到的一些東西做下筆記,希望也能幫到你,如果是要看源碼解讀的朋友們可以移步其他文章了哈~
1. nonnull宏定義
給兩個(gè)宏之間的變量自動(dòng)添加nonnull
修飾,如果需要個(gè)別nullable
則單獨(dú)標(biāo)出,非常方便。
NS_ASSUME_NONNULL_BEGIN
// 中間的變量會(huì)自動(dòng)添加nonnull修飾,避免繁瑣的添加
NS_ASSUME_NONNULL_END
2.inline內(nèi)鏈函數(shù)
inline
定義的類的內(nèi)聯(lián)函數(shù),函數(shù)的代碼被放入符號(hào)表中,在使用時(shí)直接進(jìn)行替換,(像宏一樣展開),沒有了調(diào)用的開銷,效率也很高。
// 頻繁獲取異步線程,使用內(nèi)鏈函數(shù)避免調(diào)用開銷
static inline dispatch_queue_t YYMemoryCacheGetReleaseQueue() {
return dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);
}
3.異步釋放資源:調(diào)用類的方法進(jìn)行異步釋放
holder
為一個(gè)數(shù)組,直接調(diào)用數(shù)組的count
方法,進(jìn)行異步資源釋放。
dispatch_async(queue, ^{
[holder count]; // release in queue
});
4.用互斥鎖實(shí)現(xiàn)自旋鎖邏輯
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
獲取線程鎖,如果得到鎖,進(jìn)行相關(guān)邏輯,如果鎖忙,則等待10ms
(避免短時(shí)間大量循環(huán)占用資源)。
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() 函數(shù)
可參考Mattt的文章Benchmarking,主要用來測試代碼效率。
與
NSDate
或CFAbsoluteTimeGetCurrent()
偏移量不同的是,mach_absolute_time()
和CACurrentMediaTime()
是基于內(nèi)建時(shí)鐘的,能夠更精確更原子化地測量,并且不會(huì)因?yàn)橥獠繒r(shí)間變化而變化(例如時(shí)區(qū)變化、夏時(shí)制、秒突變等)
另外引用一下Mattt使用dispatch_benchmark測試代碼效率的使用實(shí)例:
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() 函數(shù)
判斷是否是主線程使用,返回值為1時(shí)為主線程
還有
[NSThread currentThread]
等