學(xué)習(xí)YYCache總結(jié)

僅僅是自己的理解,如有錯(cuò)誤的地方,請(qǐng)指正

高山仰止,景行行止

YYMemoryCache

該類主要處理將數(shù)據(jù)存放在內(nèi)存中,主要有四個(gè)方面,使用CFMutableDictionaryRef來實(shí)現(xiàn)數(shù)據(jù)的實(shí)際存儲(chǔ);使用OSSpinLockLock來保證線程的安全;使用_YYLinkedMapNode_YYLinkedMap來組織數(shù)據(jù)的存儲(chǔ)結(jié)構(gòu);使用YYMemoryCache來組織對(duì)數(shù)據(jù)的各種操作。

1、CFMutableDictionaryRef

想先說一點(diǎn)Core Foundation 框架,他是一組C語言的接口,為應(yīng)用程序提供基本的數(shù)據(jù)管理和服務(wù)功能,他和Foundation框架為相同的功能提供接口,只不過Foundation框架提供的是Objective-C的接口。

/*!
@typedef CFDictionaryRef
This is the type of a reference to immutable CFDictionarys.
*/
typedef const struct CF_BRIDGED_TYPE(NSDictionary) __CFDictionary * CFDictionaryRef;

初始化一個(gè)CFMutableDictionaryRef的實(shí)例,

CFMutableDictionaryRef _dic = CFDictionaryCreateMutable(CFAllocatorGetDefault(), 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);

添加數(shù)據(jù),看官方API可以發(fā)現(xiàn),添加數(shù)據(jù)其實(shí)有兩個(gè)方法

CF_EXPORT
void CFDictionarySetValue(CFMutableDictionaryRef theDict, const void *key, const void *value);

CF_EXPORT
void CFDictionaryAddValue(CFMutableDictionaryRef theDict, const void *key, const void *value);

看區(qū)別:

  • CFDictionarySetValue : If a key which matches this key is already present in the dictionary, only the value is changed ("add if absent, replace if present"). If no key matches the given key, the key-value pair is added to the .(如果key存在,則使用新的value替換原來的value,反之,則添加新的key-value)
  • CFDictionaryAddValue :If key which matches this key is already present in the dictionary, function does nothing ("add if absent").(如果key存在,不做任何操作,反之,添加新的key-value)

刪除指定的key

CF_EXPORT
void CFDictionaryRemoveValue(CFMutableDictionaryRef theDict, const void *key);

很容易理解的移除方式 If a key matches this key is present in the dictionary, the key-value is removed from the dictionary, otherwise this function does ("remove if present").

獲取當(dāng)前所有存儲(chǔ)的key-value 的個(gè)數(shù)

CF_EXPORT
CFIndex CFDictionaryGetCount(CFDictionaryRef theDict);

判定當(dāng)前的key是否存在

CF_EXPORT
Boolean CFDictionaryContainsKey(CFDictionaryRef theDict, const void *key);

獲取指定key的value

CF_EXPORT
const void *CFDictionaryGetValue(CFDictionaryRef theDict,  const void *key);

如果不存在該key,返回為空。

2、OSSpinLockLock

再說這個(gè)之前先了解幾種加鎖的方式,并測(cè)試一下他們的效率

NSInteger count = 100000;

double startTime,endTime;
NSLock *lock = [[NSLock alloc]init];

startTime = CFAbsoluteTimeGetCurrent();
for (NSInteger i = 0; i < count; i++) {
    [lock lock];
    
    [lock unlock];
}
endTime = CFAbsoluteTimeGetCurrent();
NSLog(@"NSLock = %f",endTime - startTime);

//引入庫#import <pthread/pthread.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
startTime = CFAbsoluteTimeGetCurrent();
for (NSInteger i = 0; i < count; i++) {
    pthread_mutex_lock(&mutex);
    pthread_mutex_unlock(&mutex);
}

endTime = CFAbsoluteTimeGetCurrent();
NSLog(@"pthread_mutex_t = %f",endTime - startTime);

//引入庫#import <libkern/OSAtomic.h>
OSSpinLock spinLock = OS_SPINLOCK_INIT;
startTime = CFAbsoluteTimeGetCurrent();
for (NSInteger i = 0; i < count; i++) {
    OSSpinLockLock(&spinLock);
    
    OSSpinLockUnlock(&spinLock);
}
endTime = CFAbsoluteTimeGetCurrent();
NSLog(@"OSSpinLock = %f",endTime - startTime);

id obj = [[NSObject alloc]init];
startTime = CFAbsoluteTimeGetCurrent();
for (NSInteger i = 0; i < count; i++) {
    @synchronized(obj) {
        
    }
}
endTime = CFAbsoluteTimeGetCurrent();
NSLog(@"@synchronized = %f",endTime - startTime);

看一下打印值:
2016-01-17 10:35:06.793 YYCacheStudy[4751:442986] NSLock = 0.003598
2016-01-17 10:35:06.796 YYCacheStudy[4751:442986] pthread_mutex_t = 0.002747
2016-01-17 10:35:06.797 YYCacheStudy[4751:442986] OSSpinLock = 0.001237
2016-01-17 10:35:06.811 YYCacheStudy[4751:442986] @synchronized = 0.013879

但是在新版iOS中不能保證安全,看大神的博客《不再安全的 OSSpinLock》

其他的數(shù)據(jù)結(jié)構(gòu)組成,就是簡(jiǎn)單的鏈表格式,不多說,還有各種外層封裝,就是針對(duì)鏈表的操作,都是基礎(chǔ)知識(shí),就不寫了。

YYKVStorage

上述的YYMemoryCache將數(shù)據(jù)寫到內(nèi)存里,一旦程序程序關(guān)閉或者達(dá)到內(nèi)存警告,則數(shù)據(jù)就會(huì)消息。該類主要寫了兩種將數(shù)據(jù)寫到本地的方法,實(shí)現(xiàn)了離線緩存。兩種方式,一種是利用數(shù)據(jù)庫SQLite,另一種采取的是寫文件的方式。至于數(shù)據(jù)庫,由于之前一直使用FMDB,導(dǎo)致對(duì)sqlite的使用并不熟,正好就這個(gè)機(jī)會(huì)學(xué)習(xí)一下。

sqlite
文件操作
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容