如何防止错误线程上的域访问

时间:2017-07-27 16:14:31

标签: ios multithreading realm

我有一个使用Realm执行CRUD操作的模型类。

我正在尝试在串行队列上执行所有操作。

我已经声明了队列属性:

@property (nonatomic, strong) dispatch_queue_t realmQueue;
@property (strong,nonatomic) RLMRealm *secureRealm;

我用singleton初始化队列:

+ (id)sharedInstance {
    static ActivityManager *sharedManager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedManager = [[self alloc] init];

    });

    return sharedManager;
}

-(id)init{
    self.realmQueue = dispatch_queue_create("realm_activity", DISPATCH_QUEUE_SERIAL);
    dispatch_async(self.realmQueue, ^{
    _secureRealm = [RLMRealm defaultRealm];
    });
    return self;
}

-(NSArray *)getDataOnSettingFilter{

    NSMutableArray *activityArr = [NSMutableArray array];
    NSString *filterSQL = //;

    RLMResults *activityResults = [[[self getActivitySource]activities] objectsWhere:filterSQL];

    dispatch_async(self.realmQueue, ^{
        [_secureRealm beginWriteTransaction];

        for (RealmActivity *activity in activityResults){

        //modify realm properties

        [_secureRealm addOrUpdateObject:activity];
        [activityArr addObject:activity];
    }
        [_secureRealm commitWriteTransaction];
    });
    return [activityArr copy];
}

当我使用以下方法调用上述方法时:

  [[ActivityManager sharedInstance]getDataOnSettingFilter]

我发现一个崩溃,说从一个不正确的线程访问领域。

我在这里做错了什么。如何检查我是否总是在正确的线程上调用域?

1 个答案:

答案 0 :(得分:1)

您不应该存储对单例Realm实例的引用,因为您无法确保始终从同一个线程访问它。正如Realm文档所述,

  

RLMRealm,RLMResults或RLMArray或托管实例的实例   RLMObject是线程限制的,这意味着它们只能被使用   在它们被创建的线程上,否则是一个例外   抛出

意味着您永远不应该尝试使用RLMRealm *realm = [RLMRealm defaultRealm];来创建单个Realm实例,而不是尝试从您的应用中访问它。

您可以尝试使用RLMThreadSafeReference创建对可以在线程之间安全共享的Realm个对象的引用,但正如文档的Passing instances across threads部分所述,这些引用只能使用一次,所以他们不能作为单身人士重复使用。

但是,没有必要这样做,因为每次调用RLMRealm *realm = [RLMRealm defaultRealm];时,框架会自动创建对您正在使用的线程上当前使用的Realm的引用,使您能够安全地进行交互只要你不离开那个帖子就可以了。

以线程安全的方式使用Realm的最佳方法是,每次在线程之间移动并需要访问{时,使用Realm创建对RLMRealm *realm = [RLMRealm defaultRealm];的新引用{1}}。这样您就可以确保永远不会得到不正确的线程异常。