ios - sobre - Reino al que se accede desde un hilo incorrecto
libros sobre youtube pdf (1)
Desde Realm docs : los objetos RLMRealm
no son seguros para subprocesos y no se pueden compartir entre subprocesos, por lo que debe obtener una instancia de RLMRealm
en cada subproceso / RLMRealm
en la que desee leer o escribir.
También desde documentos de Realm : los objetos RLMRealm
se almacenan en caché internamente por Realm, y llamar a este método varias veces en un solo subproceso dentro de una única iteración del ciclo de ejecución normalmente devolverá el mismo objeto RLMRealm
.
Sabiendo esto, modifiqué el ejemplo de código para obtener el RLMRealm
directamente desde el bloque dispatch_async
donde se usa, sin incurrir en una penalización de rendimiento, ya que está en caché.
También noté que un AccelerationEvent
se pasó por los hilos, lo que tampoco está permitido. Entonces, este ejemplo de código modificado pasa NSString
s en los hilos en su lugar.
self.realmQueue = dispatch_queue_create("db", DISPATCH_QUEUE_SERIAL);
self.motionManager = [[CMMotionManager alloc] init];
self.motionManager.accelerometerUpdateInterval = 0.001;
__block int i = 0;
__block BOOL shouldBeginWriteTransaction = YES;
[self.motionManager startAccelerometerUpdatesToQueue:[[NSOperationQueue alloc] init] withHandler:^(CMAccelerometerData *accelerometerData, NSError *error) {
dispatch_async(self.realmQueue, ^{
RLMRealm *realm = [RLMRealm realmWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"temp"]];
if (shouldBeginWriteTransaction) {
[realm beginWriteTransaction];
shouldBeginWriteTransaction = NO;
}
AccelerationEvent *event = [[AccelerationEvent alloc] init];
event.x = accelerometerData.acceleration.x;
event.y = accelerometerData.acceleration.x;
event.z = accelerometerData.acceleration.y;
event.time = [NSDate date];
[realm addObject:event];
if (i % 1000) {
NSString *xString = [NSString stringWithFormat:@"%f", event.x];
NSString *yString = [NSString stringWithFormat:@"%f", event.y];
NSString *zString = [NSString stringWithFormat:@"%f", event.z];
dispatch_async(dispatch_get_main_queue(), ^{
self.xLabel.text = xString;
self.yLabel.text = yString;
self.zLabel.text = zString;
});
}
if (i % 10000 == 0) {
NSDate *startDate = [NSDate date];
[realm commitWriteTransaction];
NSLog(@"save time: %f", [[NSDate date] timeIntervalSinceDate:startDate]);
shouldBeginWriteTransaction = YES;
}
i++;
});
}];
No ejecuté este código para confirmar que funciona, así que avíseme si esto todavía no resuelve el problema.
Estoy usando la cola serie GCD para trabajar con el reino. La aplicación se bloquea con el Realm accessed from incorrect thread
excepción de Realm accessed from incorrect thread
cuando GCD comienza a cambiar los subprocesos de la cola. ¿Hay alguna manera de enlazar el reino dado con un hilo usando GCD API?
Aquí hay un ejemplo rápido
self.realmQueue = dispatch_queue_create("db", DISPATCH_QUEUE_SERIAL);
__block RLMRealm *realm = nil;
dispatch_async(self.realmQueue, ^{
realm = [RLMRealm realmWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"temp"]];
});
self.motionManager = [[CMMotionManager alloc] init];
self.motionManager.accelerometerUpdateInterval = 0.001;
__block int i = 0;
__block BOOL shouldBeginWriteTransaction = YES;
[self.motionManager startAccelerometerUpdatesToQueue:[[NSOperationQueue alloc] init] withHandler:^(CMAccelerometerData *accelerometerData, NSError *error) {
dispatch_async(self.realmQueue, ^{
if (shouldBeginWriteTransaction) {
[realm beginWriteTransaction];
shouldBeginWriteTransaction = NO;
}
AccelerationEvent *event = [[AccelerationEvent alloc] init];
event.x = accelerometerData.acceleration.x;
event.y = accelerometerData.acceleration.x;
event.z = accelerometerData.acceleration.y;
event.time = [NSDate date];
[realm addObject:event];
if (i % 1000) {
dispatch_async(dispatch_get_main_queue(), ^{
self.xLabel.text = [NSString stringWithFormat:@"%f", event.x];
self.yLabel.text = [NSString stringWithFormat:@"%f", event.y];
self.zLabel.text = [NSString stringWithFormat:@"%f", event.z];
});
}
if (i % 10000 == 0) {
NSDate *startDate = [NSDate date];
[realm commitWriteTransaction];
NSLog(@"save time: %f", [[NSDate date] timeIntervalSinceDate:startDate]);
shouldBeginWriteTransaction = YES;
}
i++;
});
}];