какао: шаблон проектирования отправки

-(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
    }
}

Мне нужно запустить personToPoint() в основной очереди, чтобы понять суть, а метод usePoint() не нужно запускать в основной очереди и выполнять долго. Однако при запуске usePoint(point) точке не было присвоено значение, поскольку используется dispatch_async. При использовании метода dispatch_sync программа будет заблокирована. как я могу использовать точку после того, как она была назначена?

ОБНОВЛЕНИЕ: как реализовать шаблон следующего кода:

-(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
}

person NOrder    schedule 20.08.2012    source источник


Ответы (1)


Что-то вроде следующего будет работать. Вы также можете поместить весь цикл for в один dispatch_async() и позволить основному потоку одновременно отправлять все функции usePoint().

-(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
            });
        });
    }
}

Решение обновленного вопроса:

Вы используете тот же базовый шаблон, что и предложенный выше. То есть вы отправляете то, что вам нужно сделать в основном потоке, в основной поток, а затем вкладываете отправку обратно в рабочую очередь по умолчанию внутри отправки основного потока. Таким образом, когда основной поток завершает свою работу, он отправляет трудоемкие части для выполнения в другом месте.

-(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
        });    
    });
}

Обратите внимание, что в вашем коде была ошибка, так как вы не можете добавить CGPoint к NSArray, поскольку они не являются объектами. Вы должны обернуть их в NSValue, а затем развернуть в usePoint(). Я использовал расширение для NSValue, которое работает только на iOS. В Mac OS X вам нужно заменить это на [NSValue valueWithPoint:NSPointToCGPoint(point)].

person torrey.lyons    schedule 20.08.2012