(iphone)将 NSThread* 作为成员变量是一个坏主意?
我的自定义类之一将 NSThread* 作为成员变量。
我通过设置变量(isNeedToExit)让线程退出。
然后对线程对象调用释放[myThreadrelease];
我想让线程先退出并调用释放调用。
但转念一想,在线程注意到布尔值更改并退出之前,可能会调用释放调用。
(因为线程并不是不断的查看值看是否需要退出)
@property(nonatomic,retain)NSThread* myThread;
- (void) dealloc
{
...
[myThread release];
myThread = nil;
...
[super dealloc];
}
- (id) initMyClass
{
if(self = [super init] )
{
...
NSThread* aThread = [[NSThread alloc] initWithTarget: self selector:@selector(theThreadMain) object: nil];
self.myThread = aThread;
[aThread release];
[self.myThread start];
..
}
return self;
}
- (void) theThreadMain
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
// Add your sources or timers to the run loop and do any other setup.
NSRunLoop *runloop = [NSRunLoop currentRunLoop];
[runloop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode];
do
{
// Start the run loop but return after each source is handled.
SInt32 result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 10, YES);
}
while (self.isNeedToExit == false);
[pool release];
SYSLOG(LOG_DEBUG, "thread exiting");
}
我想将 [myThread release] 调用(现在在类的 dealloc 处)移至 theThreadMain 的最后一行。
不确定当线程是另一个类的成员变量时,这是否是停止线程的正确方法。
谢谢
One of my custom class has NSThread* as member variable.
I'm letting the thread exit by setting a variable(isNeedToExit).
Then call a release on the thread object [myThread release];
I intended the thread to exit first and release call gets called.
But on second thought, release call might get called before the thread notices the boolean value changed and exit.
(Because the thread is not constantly looking at the value to see if it needs to exit)
@property (nonatomic, retain) NSThread* myThread;
- (void) dealloc
{
...
[myThread release];
myThread = nil;
...
[super dealloc];
}
- (id) initMyClass
{
if(self = [super init] )
{
...
NSThread* aThread = [[NSThread alloc] initWithTarget: self selector:@selector(theThreadMain) object: nil];
self.myThread = aThread;
[aThread release];
[self.myThread start];
..
}
return self;
}
- (void) theThreadMain
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
// Add your sources or timers to the run loop and do any other setup.
NSRunLoop *runloop = [NSRunLoop currentRunLoop];
[runloop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode];
do
{
// Start the run loop but return after each source is handled.
SInt32 result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 10, YES);
}
while (self.isNeedToExit == false);
[pool release];
SYSLOG(LOG_DEBUG, "thread exiting");
}
I thought of moving [myThread release] call (now at the class's dealloc) to last line of theThreadMain..
Not sure if this is the correct way to stop a thread when it is a member variable of another class.
Thank you
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
事实上,你最初的假设更正确。但是,您当前的实现将不起作用,因为永远不会调用dealloc。
你的类被 NSThread 保留在 initWithTarget:selector:object 中,直到线程执行完毕才会被释放。因此,只要线程正在执行,您的类实例就不会被释放。
解决该问题的一种方法是向您的类添加一个“取消”方法来停止线程。例如:
这将导致线程停止,并允许您的类被释放(一旦线程停止)。您需要确保类的所有用户都知道在释放类之前需要调用“取消”。例如:
更传统的解决方案是简单地子类化 NSThread。
Actually, your initial assumption was more correct. Your current implementation, however, will not work because
dealloc
will never be called.Your class is retained by NSThread in
initWithTarget:selector:object
and will not be released until the thread finishes executing. Therefore, your class instance will not be deallocated as long as the thread is executing.One way to solve the problem is to add a "cancel" method to your class that stops the thread. E.g.:
That will cause the thread to stop and will allow your class to be deallocated (once the thread stops.) You need to ensure that all users of your class know that "cancel" needs to be called before the class is released. E.g.:
A more traditional solution would be to simply subclass NSThread.