Есть ли способ войти в многопоточный режим Какао, не создавая фальшивый NSThread? - PullRequest
6 голосов
/ 06 мая 2011

Руководство по нитям Apple говорит:

Для многопоточных приложений платформы Какао используют блокировки и другие формы внутренней синхронизации, чтобы гарантировать их правильное поведение. Однако для предотвращения снижения производительности этих блокировок в однопоточном случае Cocoa не создает их, пока приложение не создаст свой первый новый поток с помощью класса NSThread. Если вы порождаете потоки, используя только подпрограммы потоков POSIX, Cocoa не получает уведомлений, которые ему нужны, чтобы знать, что ваше приложение теперь многопоточное. Когда это происходит, операции, включающие платформы Cocoa, могут дестабилизировать или привести к сбою вашего приложения.

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

В моем приложении для iOS я запускаю несколько потоков из кода C ++ с самого начала. Чтобы приложение работало правильно, в соответствии с документом, приведенным выше, я создаю фальшивый NSThread, который ничего не делает. Мне не нравится создавать такой бесполезный код (обычно это WTF, когда вы впервые читаете его), и я хочу избегать этого. Есть ли лучший способ перевести мое приложение в многопоточный режим?

1 Ответ

3 голосов
/ 02 июля 2011

Если оно есть, оно не является общедоступным и может быть нестабильным.

Если вы нажимаете WTF в своем коде, переименуйте и перенастройте все, чтобы это имело смысл.Поскольку вам также необходим фиктивный объект с фиктивным селектором, вы можете просто добавить одноразовый класс, например CocoaMultithreading, и затем отправить ему сообщение +beginMultithreading:

@interface CocoaMultithreading : NSObject
+ (void)beginMultithreading;
@end

int
main(void) {
    [CocoaMultithreading beginMultithreading];
    /* now do whatever you want */
    return EXIT_SUCCESS;
}

@implementation CocoaMultithreading
+ (void)dummyThread:(id)unused
{
    (void)unused;
}

+ (void)beginMultithreading
{
    [NSThread detachNewThreadSelector:@selector(dummyThread:)
            toTarget:self withObject:nil];
}
@end

Это должно быть достаточно явным.

ETA: Александр Стаубо отмечает, что, начиная с OS X 10.5 / iOS 2.0, вы можете вызывать метод -start на NSThread напрямую, поэтомуСамый простой способ включить многопоточность Какао будет выглядеть так:

void XXXActivateCocoaMultithreading(void) { [[NSThread new] start]; }

Затем в вашей main функции:

XXXActivateCocoaMultithreading();

Это также явно, но гораздо менее беспорядочно,(XXX служит для напоминания о префиксе нестатических функций. Поскольку статические функции часто становятся нестатичными в какой-то момент, префикс их всех с самого начала - хороший ход.)

...