Проблема многопоточности с ActivityWeel - PullRequest
0 голосов
/ 15 апреля 2011

У меня проблема с многопоточностью. Я получил этот кусок кода (drawActivityWheel делает UIActivityIndicatorView):

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[NSThread detachNewThreadSelector: @selector(drawActivityWheel) toTarget:self withObject:nil];
//Do some actions
[NSThread detachNewThreadSelector: @selector(removeActivityWheel) toTarget:self withObject:nil];            
[pool release];

И это работает, но я получил много сообщений в консоли, говорящих:

*** __NSAutoreleaseNoPool(): Object 0x758a210 of class __NSArrayM autoreleased with no pool in place - just leaking
*** __NSAutoreleaseNoPool(): Object 0x6e111a0 of class UIView autoreleased with no pool in place - just leaking   
*** __NSAutoreleaseNoPool(): Object 0x6e183c0 of class UISegmentedControl autoreleased with no pool in place - just leaking

Я прочитал что-то, что, возможно, я должен использовать что-то вроде:
[self executeSelectorOnMainThread: @selector (drawActivityWheel) withObject: nil waitUntilDone: NO]

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

Спасибо за твоих друзей!

Ответы [ 3 ]

2 голосов
/ 15 апреля 2011

Вам нужно было добавить NSAutoreleasePool в методы вашего отсоединения.

-(void)drawActivityWheel {
   NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
   // your threaded code here
   [pool drain];
}
1 голос
/ 15 апреля 2011

Вам необходимо реализовать точки входа в ваши потоки следующим образом:

- (void) drawActivityWheel {
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    //do work here
    [pool drain];
}

- (void) removeActivityWheel {
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    //do work here
    [pool drain];
}

Обратите внимание, что если ваши потоки долговечны, рекомендуется немного другой шаблон .

0 голосов
/ 15 апреля 2011

Ответы, которые уже даны, охватывают вопрос, поставленный адекватно, я бы просто добавил, что performSelectorOnMainThread:withObject:waitUntilDone: не просто предпочтителен для всего, что говорит с UIKit, он в основном требуется, так как до iOS 4.0 UIKit вообще не был безопасным для потоков и даже в 4.0+ это только очень избирательно безопасно звонить из других потоков. Не гарантируется безопасное создание UIActivityIndicatorView в фоновом потоке или добавление его в другое представление. Поэтому то, что вы делаете, может произойти сбой случайно или в будущих версиях ОС, или привести к любой другой части неопределенного поведения.

Сведения об этом см. В введении к UIKit , в частности:

Примечание: По большей части, классы UIKit следует использовать только с Основная тема приложения. Это особенно актуально для производных классов от UIResponder или с участием манипулирование пользователем вашего приложения интерфейс в любом случае.

Если ваши попытки вызвать ваш метод в главном потоке оказались безрезультатными, то, скорее всего, ваш основной поток заблокирован. Селектор, который вы передадите, будет запланирован на выполнение, как только это будет возможно, но это просто еще одна вещь в списке того, что нужно сделать в этом потоке. Так что, если что-то еще в настоящее время блокирует, тогда это не будет сделано до тех пор, пока эта вещь не закончится, и в этот момент вы вполне можете закончить с рисованием и удалением, происходящим почти атомарно.

...