YYCache的YYKVStorage类中的有sqlite3_finalize(stmt)调用时报错一劳永逸无损修复
.h
- #import "YYKVStorage.h"
- NS_ASSUME_NONNULL_BEGIN
- @interface YYKVStorage (Fix)
- @property (nonatomic, readonly) NSString *path; ///< The path of this storage.
- @property (nonatomic, readonly) YYKVStorageType type; ///< The type of this storage.
- @property (nonatomic) BOOL errorLogsEnabled; ///< Set `YES` to enable error logs for debug.
- @end
- NS_ASSUME_NONNULL_END
复制代码 .m
- #import "YYKVStorage+Fix.h"
- #import <UIKit/UIKit.h>
- #import <time.h>
- #if __has_include(<sqlite3.h>)
- #import <sqlite3.h>
- #else
- #import "sqlite3.h"
- #endif
- @interface YYKVStorage ()
- {
- dispatch_queue_t _trashQueue;
-
- NSString *_path;
- NSString *_dbPath;
- NSString *_dataPath;
- NSString *_trashPath;
-
- sqlite3 *_db;
- CFMutableDictionaryRef _dbStmtCache;
- NSTimeInterval _dbLastOpenErrorTime;
- NSUInteger _dbOpenErrorCount;
- }
- @end
- @implementation YYKVStorage (Fix)
- #pragma mark - db
- - (BOOL)_dbOpen {
- if (_db) return YES;
-
- int result = sqlite3_open(_dbPath.UTF8String, &_db);
- if (result == SQLITE_OK) {
- CFDictionaryKeyCallBacks keyCallbacks = kCFCopyStringDictionaryKeyCallBacks;
- CFDictionaryValueCallBacks valueCallbacks = {0};
- _dbStmtCache = CFDictionaryCreateMutable(CFAllocatorGetDefault(), 0, &keyCallbacks, &valueCallbacks);
- _dbLastOpenErrorTime = 0;
- _dbOpenErrorCount = 0;
- return YES;
- } else {
- _db = NULL;
- if (_dbStmtCache) {
- CFIndex size = CFDictionaryGetCount(_dbStmtCache);
- CFTypeRef *valuesRef = (CFTypeRef *)malloc(size * sizeof(CFTypeRef));
- CFDictionaryGetKeysAndValues(_dbStmtCache, NULL, (const void **)valuesRef);
- const sqlite3_stmt **stmts = (const sqlite3_stmt **)valuesRef;
- for (CFIndex i = 0; i < size; i ++) {
- sqlite3_stmt *stmt = stmts[i];
- sqlite3_finalize(stmt);
- }
- free(valuesRef);
- CFRelease(_dbStmtCache);
- }
- _dbStmtCache = NULL;
- _dbLastOpenErrorTime = CACurrentMediaTime();
- _dbOpenErrorCount++;
-
- // if (_errorLogsEnabled) {
- // NSLog(@"%s line:%d sqlite open failed (%d).", __FUNCTION__, __LINE__, result);
- // }
- return NO;
- }
- }
- - (BOOL)_dbClose {
- if (!_db) return YES;
-
- int result = 0;
- BOOL retry = NO;
- BOOL stmtFinalized = NO;
-
- if (_dbStmtCache) {
- CFIndex size = CFDictionaryGetCount(_dbStmtCache);
- CFTypeRef *valuesRef = (CFTypeRef *)malloc(size * sizeof(CFTypeRef));
- CFDictionaryGetKeysAndValues(_dbStmtCache, NULL, (const void **)valuesRef);
- const sqlite3_stmt **stmts = (const sqlite3_stmt **)valuesRef;
- for (CFIndex i = 0; i < size; i ++) {
- sqlite3_stmt *stmt = stmts[i];
- sqlite3_finalize(stmt);
- }
- free(valuesRef);
- CFRelease(_dbStmtCache);
- }
- _dbStmtCache = NULL;
-
- do {
- retry = NO;
- result = sqlite3_close(_db);
- if (result == SQLITE_BUSY || result == SQLITE_LOCKED) {
- if (!stmtFinalized) {
- stmtFinalized = YES;
- sqlite3_stmt *stmt;
- while ((stmt = sqlite3_next_stmt(_db, nil)) != 0) {
- sqlite3_finalize(stmt);
- retry = YES;
- }
- }
- } else if (result != SQLITE_OK) {
- // if (_errorLogsEnabled) {
- // NSLog(@"%s line:%d sqlite close failed (%d).", __FUNCTION__, __LINE__, result);
- // }
- }
- } while (retry);
- _db = NULL;
- return YES;
- }
- @end
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |