Проблема многопоточности с ActivityWeel

У меня возникла проблема с многопоточностью. Я получил этот фрагмент кода (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 PerformSelectorOnMainThread:@selector(drawActivityWheel) withObject:nil waitUntilDone:NO]

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

Спасибо за помощь друзья!


person FelipeDev.-    schedule 15.04.2011    source источник


Ответы (3)


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

-(void)drawActivityWheel {
   NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
   // your threaded code here
   [pool drain];
}
person rckoenes    schedule 15.04.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];
}

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

person aroth    schedule 15.04.2011

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

Для получения информации об этом см. введение в UIKit., в частности:

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

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

person Tommy    schedule 15.04.2011