我遇到了MultiThreading问题。 我得到了这段代码(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]
但没有任何反应。活动weel没有显示。 我相信我以糟糕的方式使用线程,请让我知道它是如何工作的!
谢谢你的帮助哥们!
答案 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或涉及 操纵应用程序的用户 以任何方式接口。
如果你试图在主线程上调用你的方法似乎没有效果,那么很可能你的主线程被阻止了。您传递的选择器将被安排在可能的情况下尽快执行,但这只是在该线程上要完成的事情列表上的另一件事。因此,如果其他东西当前正在阻止,那么在该事情结束之前不会完成,此时你可能最终会进行绘制并删除除了原子之外的所有内容。