NSOperationQueue не повторное использование потока на iPhone - PullRequest
5 голосов
/ 07 января 2010

Я использую iPhone SDK 3.1.2, и следующий код показывает, что NSOperationQueue не использует поток для каждой задачи.

Код не имеет проблем на Snow Leopard.

- (void)applicationDidFinishLaunching:(UIApplication *)application {    

    // Override point for customization after app launch    
    [window addSubview:viewController.view];
    [window makeKeyAndVisible];

    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    [queue setMaxConcurrentOperationCount:1];
    for(int i = 0; i < 100; i++) {
        NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run) object:nil];
        [queue addOperation:op];
        [op release];
    }
}

- (void)run {
    static int tc = 0;
    if([[NSThread currentThread] isMainThread]) {
        NSLog(@"MAIN THREAD");
        return;
    } else if([[NSThread currentThread] name] == nil) {
        [[NSThread currentThread] setName:[NSString stringWithFormat:@"THREAD_%d", tc++]];
    }
    NSLog(@"%@", [[NSThread currentThread] name]);
}

Вывод показывает, что он создает 100 потоков для выполнения 100 задач.

2010-01-07 11:46:03.502 OperationQueueTest[7911:4503] THREAD_0
2010-01-07 11:46:03.506 OperationQueueTest[7911:4d03] THREAD_1
2010-01-07 11:46:03.507 OperationQueueTest[7911:4807] THREAD_2
2010-01-07 11:46:03.510 OperationQueueTest[7911:4d07] THREAD_3
2010-01-07 11:46:03.514 OperationQueueTest[7911:5007] THREAD_4
2010-01-07 11:46:03.516 OperationQueueTest[7911:4f0b] THREAD_5
2010-01-07 11:46:03.518 OperationQueueTest[7911:4e0f] THREAD_6
...
2010-01-07 11:46:03.740 OperationQueueTest[7911:4ea7] THREAD_97
2010-01-07 11:46:03.744 OperationQueueTest[7911:4dcf] THREAD_98
2010-01-07 11:46:03.746 OperationQueueTest[7911:460f] THREAD_99

Ответы [ 3 ]

9 голосов
/ 07 января 2010

NSOperationQueue предназначен для объединения и повторного использования потоков наиболее эффективным способом, и в этом случае, похоже, было решено, что повторное использование потоков не является лучшим способом.

Тестовый код имеет свои применения (и, возможно, вы, возможно, определили угловой случай, когда NSOperationQueue не делает наиболее эффективную вещь), но это не означает, что NSOperationQueue всегда ужасно неэффективен при работе с реальным кодом в реальном жизнь; на самом деле мой собственный опыт был наоборот.

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

Кроме того, если вам все еще любопытно, вы можете попробовать записать имена потоков в массив строк NSStrings, а затем распечатать все в конце тестового кода, вместо того, чтобы регистрировать по ходу дела - это значительно сократить объем работы, выполняемой каждой операцией NSInvocation.

2 голосов
/ 07 января 2010

Реализация NSOperation / NSOperationQueue в Snow Leopard теперь основана на GCD.

iPhone по-прежнему использует старую реализацию Leopard. Таким образом, вы можете ожидать разные результаты на каждой платформе (не говоря уже о совершенно другом оборудовании).

Возможно, что создание новых потоков является наиболее эффективным способом выполнения задач, которые вы задаете NSOperationQueue.

0 голосов
/ 06 июля 2015

NSOperationQueue выполняет добавленные операции асинхронно (в отдельном потоке). Поэтому, если мы распечатаем информацию о потоке, возможно, что большую часть времени мы получим один и тот же объект потока.

Объект NSOperation, добавленный в NSOperationQueue, будет другим, но объекты потока могут быть одинаковыми.

- (void)operaitonqueueTest
{

    _opQueue = [[NSOperationQueue alloc] init];
    [_opQueue setMaxConcurrentOperationCount:5];
    for(int i = 0; i < 50; i++) {
        NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run) object:nil];
        [_opQueue addOperation:op];
    }
}

- (void)run {
    if([[NSThread currentThread] isMainThread]) {
        NSLog(@"MAIN THREAD");
        return;
    }
    NSLog(@"currentThread = %@", [NSThread currentThread]);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...