-(void) test{
for(Person *person in persons){
__block CGPoint point;
dispatch_async(dispatch_get_main_queue(), ^{
point = [self.myview personToPoint:person];
});
usePoint(point); // take a long time to run
}
}
I need to run personToPoint()
in the main queue to get the point, and usePoint()
method doesn't need to run in main queue and take a long time to run. However, when running usePoint(point)
, point has not been assigned value because using dispatch_async. If using dispatch_sync method, the program will be blocked. the how can I using point after it has been assigned?
UPDATE: how to implement the pattern of the following code:
-(void) test{
NSMutableArray *points = [NSMutableArray array];
for(Person *person in persons){
__block CGPoint point;
dispatch_async(dispatch_get_main_queue(), ^{
point = [self.myview personToPoint:person];
[points addObject:point];
});
}
usePoint(points); // take a long time to run
}
Something like the following would work. You might also put the entire for loop inside one dispatch_async() and let the main thread dispatch all the usePoint() functions at once.
-(void) test{
for(Person *person in persons){
dispatch_async(dispatch_get_main_queue(), ^{
CGPoint point = [self.myview personToPoint:person];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
usePoint(point); // take a long time to run
});
});
}
}
Solution for Updated question:
You use the same basic pattern as suggested above. That is you dispatch the stuff you need to do on the main thread to the main thread and then nest a dispatch back to a default work queue inside the main thread dispatch. Thus when the main thread finishes its work it will dispatch off the time consuming parts to be done elsewhere.
-(void) test{
dispatch_async(dispatch_get_main_queue(), ^{
NSMutableArray *points = [NSMutableArray array];
for (Person *person in persons){
CGPoint point = [self.myview personToPoint:person];
[points addObject:[NSValue valueWithCGPoint:point]];
}
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
usePoint(points); // take a long time to run
});
});
}
Note that there was an error in your code as you can't add CGPoint
's to an NSArray
since they are not objects. You have to wrap them in an NSValue
and then unwrap them in usePoint()
. I used an extension to NSValue
that only works on iOS. On Mac OS X you'd need to replace this with [NSValue valueWithPoint:NSPointToCGPoint(point)]
.