ActivityWeel的多线程问题

时间:2011-04-15 12:49:02

标签: iphone multithreading cocoa-touch uiactivityindicatorview

我遇到了MultiThreading问题。 我得到了这段代码(drawActivityWheel创建了一个UIActivityIndi​​catorView):

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]

但没有任何反应。活动weel没有显示。 我相信我以糟糕的方式使用线程,请让我知道它是如何工作的!

谢谢你的帮助哥们!

3 个答案:

答案 0 :(得分:2)

您需要在分离的方法中添加NSAutoreleasePool。

-(void)drawActivityWheel {
   NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
   // your threaded code here
   [pool drain];
}

答案 1 :(得分:1)

您需要实现这样的线程入口点:

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

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

请注意,如果您的主题是长寿的,建议使用slightly different pattern

答案 2 :(得分:0)

已经给出的答案涵盖了充分说明的问题,我只想补充说performSelectorOnMainThread:withObject:waitUntilDone:不仅仅是与UIKit对话的首选,它主要是因为在iOS 4.0之前UIKit不是线程安全的在所有甚至是4.0+中,从其他线程调用它只是非常有选择性。保证在后台线程上创建UIActivityIndicatorView或将其添加到另一个视图是安全的。因此,您正在做的事情可能会随机或在未来的操作系统版本上崩溃,或导致任何其他未定义的行为。

有关权威,请参阅the introduction to UIKit,具体来说:

  

注意:在大多数情况下,UIKit类   应该只用于   应用程序的主要线程。这是   对于派生的类尤其如此   来自UIResponder或涉及   操纵应用程序的用户   以任何方式接口。

如果你试图在主线程上调用你的方法似乎没有效果,那么很可能你的主线程被阻止了。您传递的选择器将被安排在可能的情况下尽快执行,但这只是在该线程上要完成的事情列表上的另一件事。因此,如果其他东西当前正在阻止,那么在该事情结束之前不会完成,此时你可能最终会进行绘制并删除除了原子之外的所有内容。