IOS CoreData心得之连接池

IOS的第一个项目,要弄一个离线版,要读存数据库,当然选择了CoreDate

随之出现了一点问题,

1.在大量使用GCD和block以后发现程序会卡死在executefetchrequest执行

  网上搜了一搜,发现问题了,原来在线程中NSManagedObjectContext会创建一些私有方法。跨线程使用时候就会出问题。

  解决办法就是多个线程执行时候创建多个NSManagedObjectContext管理。关联到NSPersistentStoreCoordinator

  (这个地方,反复想了想,可能是我的用法用错了,NSManagedObjectContext的创建仅仅在多线程里使用,别的用默认的即可)

2.那好,既然发现了问题那就解决呗,多个线程执行时候创建多个NSManagedObjectContext管理,而我们的项目,没有上下拉刷新,而是采取在进入页面的时候从服务器同步数据,然后放入本地数据库,取出数据,页面reload,这样每点击一个页面就有一个多线程,那就是N个NSManagedObjectContext,那内存是蹭蹭的上涨,在ipod上闪退现象严重

  无奈啊,这两天突然间想到了一个办法,那就是模拟JDBC连接池,只是一个初步的思想,把想法说一下

  在程序打开的时候,就创建一个NSMutableArray,然后初始化N个NSManagedObjectContext,并且放入NSMutableArray,然后在查询,保存时候,查询NSMutableArray有没有可用的NSManagedObjectContext,如果有则取出,如果没有则等待,在如果有的情况下,开始操作,在操作完毕,大概是在excuteFecthRequest时候和save之后 将NSManagedObjectContext再次放入NSMutableArray,首先要保证NSMutableArray线程安全,加上单例设计模式?这些仅仅是想法,还未实现

3.大致上实现了一个连接池

#import <Foundation/Foundation.h>

@interface ContextPool : NSObject


@property (nonatomic,strong) NSMutableArray *contextArray;

@property (nonatomic,assign)  int  maxCon;

+ (instancetype)shareInstance;

- (void)initPool:(int)count;

- (NSManagedObjectContext *)getContext;

- (void)free:(NSManagedObjectContext *)context;

- (NSManagedObjectContext *)createContext;

@end

 

  

#import "ContextPool.h"

//最大连接数

static int inUsing = 0;
static ContextPool *instance = nil;

@implementation ContextPool


+ (instancetype)shareInstance {
    if (instance == nil)
    {
        @synchronized (self)
        {
            if (instance == nil)
            {
                instance = [[self alloc] init];
            }
        }
    }
    return instance;
}

/**
 * 初始化连接池
 *
 */
- (void)initPool:(int)count{
    self.maxCon = count;
    self.contextArray = [[NSMutableArray alloc]init];
    for (int i=0; i<self.maxCon; i++)
    {
        [self.contextArray addObject:[self createContext]];
    }
}

/**
 *  创建context
 */
- (NSManagedObjectContext *)createContext
{
    NSManagedObjectContext *newContext = [[NSManagedObjectContext alloc]initWithConcurrencyType:NSPrivateQueueConcurrencyType];
    newContext.persistentStoreCoordinator = [[CoreDataManager instance]persistentStoreCoordinator];
    return newContext;
}

/**
 *  从池子里获取context
 */
- (NSManagedObjectContext *)getContext
{
    NSManagedObjectContext *context = nil;
    if (context == nil)
    {
        @synchronized (self)
        {
            if(context == nil)
                if (self.contextArray.count > 0)
                {
                    context = [self.contextArray objectAtIndex:0];
                    [self.contextArray removeObjectAtIndex:0];
                    NSLog(@"被取走了一个context,还剩%i",[self.contextArray count]);
                    if (context == nil)
                    {
                        //如果context为nil  则表示context失效了 重新充初始化一个放入
                        [self.contextArray addObject:[self createContext]];
                        context = [self getContext];
                    }
                    else
                    {
                        inUsing++;
                        NSLog(@"连接池的context已经被使用了:%i个",inUsing);
                    }
                }
                else
                {
                    //            NSLog(@"连接池的资源已经用完了,创建一个新的context");
                }
                if(self.maxCon==0||self.maxCon<inUsing)
                {
                    context=nil;//达到最大连接数,暂时不能获得连接了。
                }
        }
    }
    return context;
}


/**
 *  自动增加一个context
 */
- (void)incrementContext
{
    [self.contextArray addObject:[self createContext]];
}


/**
 * 释放context 并不是真正的释放,而是将context再次放入
 */
- (void)free:(NSManagedObjectContext *)context
{
    NSLog(@"%@",context);
    if ([self.contextArray containsObject:context])
    {
        return;
    }
    NSLog(@"收回之前的使用的个数%i",inUsing);
    [self.contextArray addObject:context];
    inUsing--;
    NSLog(@"收回之后的使用的个数%i",inUsing);
    NSLog(@"哈哈,收回了一个资源,现在可以使用的连接数为:%i",[self.contextArray count]);
}

//释放全部
- (void)freeAll{
    
}

@end

 

转载于:https://www.cnblogs.com/wangdongBlog/p/3633780.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值