2017-04-05 3 views
0

J'ai une file d'attente série pour recevoir les mises à jour de mouvement Gyro et Accelerometer à un intervalle de 0,01 seconde. A partir des journaux, je peux voir que deux blocs sont exécutés sur des threads différents, car NSMutableArray n'est pas thread-safe et je modifie également le tableau dans les deux blocs, est-il prudent pour moi de manipuler le tableau de cette façon?CMMotionManager avec une file d'attente série

J'ai également lu que les tâches sur une file d'attente série sont exécutées une à la fois, si seulement un des deux mouvements est surveillé, est-il sûr de modifier le tableau?

@implementation NSThread (GetSequenceNumber) 

- (NSInteger)number 
{ 
    return [[self valueForKeyPath:@"private.seqNum"] integerValue]; 
} 

@end 

@interface SensorCollector() 

@property (nonatomic, strong) NSMutableArray *array; 

@end 

@implementation SensorCollector 
- (id)init { 
    if (self = [super init]) { 
     self.motionManager = [CMMotionManager new]; 
     self.queue = [[NSOperationQueue alloc] init]; 
     self.queue.maxConcurrentOperationCount = 1; 
     _array = [NSMutableArray array]; 
    } 
    return self; 
} 

- (void)starCollect { 
    float updateInterval = 0.01;//50Hz 

    //setup sensors callback in background NSOperationQueue 
    if ([self.motionManager isAccelerometerAvailable]) { 
     [self.motionManager setAccelerometerUpdateInterval:updateInterval]; 
     [self.motionManager startAccelerometerUpdatesToQueue:self.queue withHandler:^(CMAccelerometerData *accelerometerData, NSError *error) { 
      //modify self.array here 
      NSLog(@"Acce %ld", [NSThread currentThread].number); 
     }]; 
    } 

    if ([self.motionManager isGyroAvailable]) { 
     [self.motionManager setGyroUpdateInterval:updateInterval]; 
     [self.motionManager startGyroUpdatesToQueue:self.queue withHandler:^(CMGyroData *gyroData, NSError *error) { 
      //also modify self.array here 
      NSLog(@"Gyro %ld", [NSThread currentThread].number); 
     }]; 
    } 

} 

Répondre

1

Oui, il devrait être sûr. Les blocs de gestionnaire seront exécutés séquentiellement sur votre NSOperationQueue, en raison du fait que vous avez défini maxConcurrentOperationCount = 1.

Si vous voulez être doublement sûr, vous pouvez verrouiller le tableau lors de la modifier, en effectuant les opérations à l'intérieur d'un bloc @synchronized:

@synchronized(self.array) { 
    // Modify self.array here... 
} 

Cela dit, je ne pense pas que cela est nécessaire.

+0

Merci pour votre réponse, '@ synchronized' est un peu cher cependant. – gabbler