iOS数据库操作安全

总结:

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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值