2017-07-27 4 views
0

レルムを使用してCRUD操作を実行するモデルクラスがあります。不正なスレッドでレルムアクセスを防止する方法

すべての操作をシリアルキューで実行しようとしています。

私はキューのプロパティ宣言している:私は使用して上記のメソッドを呼び出すとき

+ (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]; 
} 

と::

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

を、私はキューを初期化するためにシングルトンを使用

[[ActivityManager sharedInstance]getDataOnSettingFilter] 

レルムが間違ったスレッドからアクセスされているというクラッシュが発生します。

私はここで間違っていますか?正しいスレッドでレルムを呼び出しているかどうかを確認するにはどうすればよいですか?

答えて

1

シングルトンRealmインスタンスへの参照は、同じスレッドから常にアクセスすることができないため、格納しないでください。 Realmドキュメントの状態としては、

RLMRealm、RLMResults、またはRLMArrayのインスタンス、または管理対象インスタンスはRLMObjectの は、彼らが唯一そうでない場合は、それらが作成されたスレッド上で を使用できることを意味し、スレッド閉じ込めています例外は あなたはシングルトンRealmインスタンスを作成し、アプリからどこでもそれにアクセスしようとするよりも、するRLMRealm *realm = [RLMRealm defaultRealm];を使用しようとすることはありませんことを意味し

がスローされます。

あなたは安全にスレッド間で共有することができRealmオブジェクトへの参照を作成するために、RLMThreadSafeReferenceを使用してみてください可能性がありますが、ドキュメント状態のPassing instances across threads一環として、これらの文献には、一度だけ使用することができますので、それらは以下のように再利用することはできませんシングルトン。

RLMRealm *realm = [RLMRealm defaultRealm];を呼び出すたびに、フレームワークは現在使用しているスレッドに現在使用されているRealmへの参照を自動的に作成するため、ドンしても安全に操作できるようになりますそのスレッドを残してはいけません。スレッドセーフな方法でRealmを使用する

最良の方法はRLMRealm *realm = [RLMRealm defaultRealm];あなたは、スレッド間を移動し、あなたのRealmにアクセスする必要があるたびに使用してRealmへの新しい参照を作成することです。これにより、間違ったスレッド例外が発生することはありません。

+2

ありがとう、私は、realmキューで作成されたrealmオブジェクトがcellForRowメソッドのメインスレッドでアクセスされ、その場合も私にクラッシュを引き起こしました。レルムを使用するセルのカスタマイズが領域キューで実行されていることを確認しました。 –

関連する問題