iOS18 第三库YYCache中sqlite3_finalize(stmt)调用报错修复

打印 上一主题 下一主题

主题 726|帖子 726|积分 2178

YYCache的YYKVStorage类中的有sqlite3_finalize(stmt)调用时报错一劳永逸无损修复
.h
  1. #import "YYKVStorage.h"
  2. NS_ASSUME_NONNULL_BEGIN
  3. @interface YYKVStorage (Fix)
  4. @property (nonatomic, readonly) NSString *path;        ///< The path of this storage.
  5. @property (nonatomic, readonly) YYKVStorageType type;  ///< The type of this storage.
  6. @property (nonatomic) BOOL errorLogsEnabled;           ///< Set `YES` to enable error logs for debug.
  7. @end
  8. NS_ASSUME_NONNULL_END
复制代码
.m
  1. #import "YYKVStorage+Fix.h"
  2. #import <UIKit/UIKit.h>
  3. #import <time.h>
  4. #if __has_include(<sqlite3.h>)
  5. #import <sqlite3.h>
  6. #else
  7. #import "sqlite3.h"
  8. #endif
  9. @interface YYKVStorage ()
  10. {
  11.     dispatch_queue_t _trashQueue;
  12.    
  13.     NSString *_path;
  14.     NSString *_dbPath;
  15.     NSString *_dataPath;
  16.     NSString *_trashPath;
  17.    
  18.     sqlite3 *_db;
  19.     CFMutableDictionaryRef _dbStmtCache;
  20.     NSTimeInterval _dbLastOpenErrorTime;
  21.     NSUInteger _dbOpenErrorCount;
  22. }
  23. @end
  24. @implementation YYKVStorage (Fix)
  25. #pragma mark - db
  26. - (BOOL)_dbOpen {
  27.     if (_db) return YES;
  28.    
  29.     int result = sqlite3_open(_dbPath.UTF8String, &_db);
  30.     if (result == SQLITE_OK) {
  31.         CFDictionaryKeyCallBacks keyCallbacks = kCFCopyStringDictionaryKeyCallBacks;
  32.         CFDictionaryValueCallBacks valueCallbacks = {0};
  33.         _dbStmtCache = CFDictionaryCreateMutable(CFAllocatorGetDefault(), 0, &keyCallbacks, &valueCallbacks);
  34.         _dbLastOpenErrorTime = 0;
  35.         _dbOpenErrorCount = 0;
  36.         return YES;
  37.     } else {
  38.         _db = NULL;
  39.             if (_dbStmtCache) {
  40.         CFIndex size = CFDictionaryGetCount(_dbStmtCache);
  41.         CFTypeRef *valuesRef = (CFTypeRef *)malloc(size * sizeof(CFTypeRef));
  42.         CFDictionaryGetKeysAndValues(_dbStmtCache, NULL, (const void **)valuesRef);
  43.         const sqlite3_stmt **stmts = (const sqlite3_stmt **)valuesRef;
  44.         for (CFIndex i = 0; i < size; i ++) {
  45.             sqlite3_stmt *stmt = stmts[i];
  46.             sqlite3_finalize(stmt);
  47.         }
  48.         free(valuesRef);
  49.         CFRelease(_dbStmtCache);
  50.     }
  51.         _dbStmtCache = NULL;
  52.         _dbLastOpenErrorTime = CACurrentMediaTime();
  53.         _dbOpenErrorCount++;
  54.         
  55. //        if (_errorLogsEnabled) {
  56. //            NSLog(@"%s line:%d sqlite open failed (%d).", __FUNCTION__, __LINE__, result);
  57. //        }
  58.         return NO;
  59.     }
  60. }
  61. - (BOOL)_dbClose {
  62.     if (!_db) return YES;
  63.    
  64.     int  result = 0;
  65.     BOOL retry = NO;
  66.     BOOL stmtFinalized = NO;
  67.    
  68.         if (_dbStmtCache) {
  69.         CFIndex size = CFDictionaryGetCount(_dbStmtCache);
  70.         CFTypeRef *valuesRef = (CFTypeRef *)malloc(size * sizeof(CFTypeRef));
  71.         CFDictionaryGetKeysAndValues(_dbStmtCache, NULL, (const void **)valuesRef);
  72.         const sqlite3_stmt **stmts = (const sqlite3_stmt **)valuesRef;
  73.         for (CFIndex i = 0; i < size; i ++) {
  74.             sqlite3_stmt *stmt = stmts[i];
  75.             sqlite3_finalize(stmt);
  76.         }
  77.         free(valuesRef);
  78.         CFRelease(_dbStmtCache);
  79.     }
  80.     _dbStmtCache = NULL;
  81.    
  82.     do {
  83.         retry = NO;
  84.         result = sqlite3_close(_db);
  85.         if (result == SQLITE_BUSY || result == SQLITE_LOCKED) {
  86.             if (!stmtFinalized) {
  87.                 stmtFinalized = YES;
  88.                 sqlite3_stmt *stmt;
  89.                 while ((stmt = sqlite3_next_stmt(_db, nil)) != 0) {
  90.                     sqlite3_finalize(stmt);
  91.                     retry = YES;
  92.                 }
  93.             }
  94.         } else if (result != SQLITE_OK) {
  95. //            if (_errorLogsEnabled) {
  96. //                NSLog(@"%s line:%d sqlite close failed (%d).", __FUNCTION__, __LINE__, result);
  97. //            }
  98.         }
  99.     } while (retry);
  100.     _db = NULL;
  101.     return YES;
  102. }
  103. @end
复制代码



免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

徐锦洪

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表