ActivityWeel 的多线程问题

发布于 2024-11-01 18:07:22 字数 1021 浏览 1 评论 0原文

我遇到了多线程问题。 我得到了这段代码(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]

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

感谢各位朋友的帮助!

I got an issue with the MultiThreading thing.
I got this piece of code(drawActivityWheel makes an 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];

And it works, but i got many messages in console saying:

*** __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

I read something that maybe i should use something like:
[self performSelectorOnMainThread:@selector(drawActivityWheel) withObject:nil waitUntilDone:NO]

But nothing happens. The activity weel is not been showing.
I believe that Im using threading in a bad way, please let me know how it really works!

Thanks for ur help buddies!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

北方的巷 2024-11-08 18:07:22

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

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

You needed to add the NSAutoreleasePool in the methods your detach.

-(void)drawActivityWheel {
   NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
   // your threaded code here
   [pool drain];
}
不疑不惑不回忆 2024-11-08 18:07:22

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

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

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

请注意,如果您的线程是长期存在的,则 建议使用稍微不同的图案

You need to implement your thread entry points like this:

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

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

Note that if your threads are long-lived, a slightly different pattern is recommended.

浮生未歇 2024-11-08 18:07:22

已经给出的答案充分涵盖了问题,我只是补充一点, performSelectorOnMainThread:withObject:waitUntilDone: 不仅是与 UIKit 交互的任何内容的首选,自 iOS 4.0 之前以来,它大多是必需的UIKit 根本不是线程安全的,即使在 4.0+ 中,从其他线程调用也只是非常有选择性地安全。不保证在后台线程上创建 UIActivityIndi​​catorView 或将其添加到另一个视图的安全性。因此,您所做的事情可能会随机崩溃或在操作系统的未来版本上崩溃,或者导致任何其他未定义的行为。

有关权威信息,请参阅 UIKit 简介,具体来说:

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

如果您尝试在主线程上调用方法似乎没有效果,那么您的主线程可能被阻塞。您传递的选择器将被安排尽快执行,但这只是该线程上要做的事情列表中的另一件事。因此,如果其他事情当前正​​在阻塞,那么直到该事情完成之前它不会完成,此时您很可能最终会以原子方式发生绘制和删除。

The answers already given cover the question as put adequately, I'd just add that performSelectorOnMainThread:withObject:waitUntilDone: isn't just preferred for anything that talks to UIKit, it's mostly required since prior to iOS 4.0 UIKit wasn't threadsafe at all and even in 4.0+ it's only very selectively safe to call from other threads. It's not guaranteed to be safe to create a UIActivityIndicatorView on a background thread, or to add it to another view. So what you're doing may crash randomly or on future versions of the OS, or result in any other piece of undefined behaviour.

For authority on that, see the introduction to UIKit, specifically:

Note: For the most part, UIKit classes
should be used only from an
application’s main thread. This is
particularly true for classes derived
from UIResponder or that involve
manipulating your application’s user
interface in any way.

If your attempts to call your method on the main thread appeared to be having no effect then it's likely your main thread is blocked. The selector you pass will be scheduled to be performed as soon as it can be, but it's just another thing on the list of things to be done on that thread. So if something else is currently blocking then it won't be done until that thing finishes, at which point you may well end up with draw and remove occurring all but atomically.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文