gpt4 book ai didi

objective-c - NSThread 未加载选择器方法

转载 作者:行者123 更新时间:2023-12-03 17:41:56 25 4
gpt4 key购买 nike

在类的初始化方法中,我这样声明线程:

NSThread* myThread = [[[NSThread alloc] initWithTarget:self selector:@selector(m_run_thread) object:nil] autorelease];
[myThread start];

我还有一个 bool 值,设置为“NO”。后来在代码中我将 bool 值设置为 YES。

bool_run_progress_thread = YES;

方法m_run_thread的内容如下:

-(void) m_run_thread
{
if (bool_run_progress_thread)
{
//do processing here
}

bool_run_progress_thread = NO;
}

问题在于 m_run_thread 方法从未被访问过。我做错了什么?

附注我还尝试使用以下(和较旧的)方法设置线程:

[NSThread detachNewThreadSelector:@selector(m_run_thread) 
toTarget:self
withObject:nil];

...但也无济于事。

最佳答案

“...我只让它显示一次”是的,这正是它应该的样子。线程启动后,从开始到结束运行一次(这里暂时忽略错误),到达结束后,该线程基本上就死了。

如果你想让线程重复执行,你必须自己做好准备:

- (void) m_run_thread
{
for (;;)
{
if (bool_run_progress_thread)
{
//do processing here
bool_run_progress_thread = NO;
}
}
}

但是这段代码仍然存在很多错误:本质上,当运行时,代码形成了一个繁忙的等待循环。假设 bool_run_progress_thread 仅在短时间内为真,则后台线程应该在大部分时间处于休眠状态。相反,如果您按原样尝试代码,它反而会消耗 CPU 时间(而且是大量的)。

更好的方法是 condition variables :

@class Whatsoever 
{
NSCondition* cvar;
BOOL doProgress;
...
}
...
@end

- (void) m_run_thread
{
for (;;)
{
[cvar lock];

while (!doProgress)
{
[cvar wait];
}

doProgress = NO;
[cvar unlock];

... do work here ...
}
}

为了触发执行,您需要执行以下操作:

- (void) startProgress 
{
[cvar lock];
doProgress = YES;
[cvar signal];
[cvar unlock];
}

这样做还可以解决另一个微妙的问题:对全局标志所做的更改的可见性(您的 bool_run_progress_thread,我的 doProgess)。根据处理器及其内存顺序,在没有特殊保护的情况下所做的更改可能会也可能不会对其他线程可见。这个问题也由 NSCondition 解决。

关于objective-c - NSThread 未加载选择器方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10634093/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com