iOS数据库操作安全

来源:互联网 发布:细说php第二版微盘 编辑:程序博客网 时间:2024/06/05 05:52

总结:

1 数据库频繁操作打开关闭,手动打开关闭锁, 使用一个单例类操作数据库

2 避免同时操作一个资源使用队列串行方式


首先数据库是系统资源,就像我们操作文件一样,所以并发操作时要注意安全

在iOS上,只有一个线程能够打开数据库操作,其他线程要操作数据库必须等数据库关闭后才能打开操作。

多线程时:每个线程独立打开数据库,操作数据库,操作完后关闭数据库。打开和关闭都比较费时间,而且要手动控制打开关闭锁,在每个线程操作不频率时可用该方法。

如果多个线程频繁操作数据库,使用以上方法很容易造成系统崩溃,解决方案:开启第3种串行模式,使用一个类(单例方式)操作数据库。


sqlite3 多线程访问数据库


解决方案:开启串行模式


多线程操作数据库,使用FMDatabaseQueue来保证线程安全


FMDatabaseQueue解决这个问题的思路是:创建一个队列,然后将放入队列的block顺序执行,这样避免了多线程同时访问数据库;

如果是多线程各创建FMDatabaseQueue的实例,其实有多个队列,还是存在数据库竞争的问题,和用FMDatabase时是一样的;

让每个线程使用同一个Queue实例,问题就顺利解决了;


FMDB源码给出的思路

    + (instancetype)sharedInstance      {          static SyncObj* instance = nil;                    static dispatch_once_t onceToken;          dispatch_once(&onceToken, ^{              instance = [SyncObj new];          });          return instance;      }      -(void) safeTest      {          io_sync_safe(^{              NSLog(@"safe print -- func safeTest()");          });      }      static const void * const NTESDispatchIOSpecificKey = &NTESDispatchIOSpecificKey;      dispatch_queue_t NTESDispatchIOQueue()      {          static dispatch_queue_t queue;          static dispatch_once_t onceToken;          dispatch_once(&onceToken, ^{              queue = dispatch_queue_create("db.queue", 0);              dispatch_queue_set_specific(queue, NTESDispatchIOSpecificKey, (void *)NTESDispatchIOSpecificKey, NULL);          });          return queue;      }      typedef void(^dispatch_block)(void);      void io_sync_safe(dispatch_block block)      {          if (dispatch_get_specific(NTESDispatchIOSpecificKey))          {              NSLog(@"3. 当前线程是: %@, 当前队列是: %@ 。",[NSThread currentThread],dispatch_get_current_queue());              [NSThread sleepForTimeInterval:1];              block();          }          else          {              dispatch_sync(NTESDispatchIOQueue(), ^() {                                    NSLog(@"4. 当前线程是: %@, 当前队列是: %@ 。",[NSThread currentThread],dispatch_get_current_queue());                  [NSThread sleepForTimeInterval:1];                  block();              });          }      }  

1. 创建单利

2. 使用dispatch_queue_create创建队列


创建串行队列, 添加不同block避免同时访问



0 0