Как создать NSThread, который не является основным потоком, без немедленного выполнения селектора - PullRequest
5 голосов
/ 30 марта 2012

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

[self performSelector:@selector(doStuff) OnThread:self.myWorkerThread withObject:nil];

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

Я использую iOS и мне нужно выполнить все мои записи CoreData на writerThread.Мне нужно использовать один и тот же поток (который не является основным) каждый раз.

Ответы [ 4 ]

4 голосов
/ 30 марта 2012

Я настоятельно рекомендую вместо этого заглянуть в Grand Central Dispatch :). Вы можете легко создать очередь отправки через dispatch_queue_create или получить один из существующих параллельных потоков и отправить в него все, что захотите. Он создаст соответствующее количество потоков на основе рабочей нагрузки / состояния ОС и т. Д. Он будет выглядеть следующим образом:

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
    //Do stuff
});

Или вы можете посмотреть на его NS-коллегу, NSOperation. Я не знаю способа сделать это только с помощью NSThread. Кажется, единственный способ установить его селектор - это инициировать его одним.

EDIT Если вы хотите просто ветку, просто позвоните [[NSThread alloc] init]: p

ДОПОЛНИТЕЛЬНОЕ РЕДАКТИРОВАНИЕ: iPhone: как использовать executeSelector: onThread: withObject: waitUntilDone: метод?

Согласно этому ответу его будет сложно настроить, так как каждый поток нуждается в "основной" функции в момент его создания, иначе он ничего не будет делать ...

2 голосов
/ 30 марта 2012

Если вы действительно этого хотите и не используете GCD, тогда:

NSThread *thr = [[NSThread alloc] initWithTarget:anobject selector:@selector(doStuff) object:nil];

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

2 голосов
/ 30 марта 2012

Кажется, что проще всего было бы использовать блоки:

void (^now)(void) = ^ {
    NSDate *date = [NSDate date];
    NSLog(@"The date and time is %@", date);
};

и вызов:

now();

NSBlockOperation или dispatch_async ().

Подробнеездесь: http://pragmaticstudio.com/blog/2010/7/28/ios4-blocks-1

1 голос
/ 30 марта 2012

Если вы специально делаете это для взаимодействия с Core Data (как подсказывает ваш вопрос), и вам может потребоваться iOS 5 для вашего приложения, вы можете исследовать новый контекст управляемого объекта приватной очереди, добавленный в iOS 5. Он создает и управляет очередью потока / отправки для вас, и вы отправляете ей блоки для запуска в очереди как способ взаимодействия с ней. См. примечания к выпуску и видео сеанса WWDC для получения более подробной информации.

Обновление (май 2016 г.): новый API, добавленный в iOS 5, был -[NSManagedObjectContext initWithConcurrencyType:]. Начиная с iOS 9, более старый инициализатор устарел, наряду с типом параллелизма ограничения, который был по умолчанию до введения типов параллелизма на основе очереди. Поэтому, если вы не используете очереди для управления контекстным доступом, я настоятельно рекомендую двигаться в этом направлении.

Я бы также настоятельно рекомендовал использовать com.apple.CoreData.ConcurrencyDebug аргумент запуска во время разработки, чтобы помочь вам поймать места, где вы нарушаете правила.

...