TestObj
类是一个简单的类,它有一个方法doSomethingInBackground
我发送它performSelectorInBackground
使自己在后台线程中休眠5秒的方法。发送消息时会自动保留
@implementation TestObj
- (void)dealloc
{
NSLog(@"%@, is main thread %u", NSStringFromSelector(_cmd), [NSThread isMainThread]) ;
}
- (void)doSomethingInBackground
{
[self performSelectorInBackground:@selector(backgroundWork) withObject:nil] ;
}
- (void)backgroundWork
{
sleep(5) ;
}
@end
我alloc和初始化实例,并将其发送doSomethingInBackground
消息,并指派nil
它以尽快将其释放。
TestObj *obj = [[TestObj alloc] init] ;
[obj doSomethingInBackground] ;
obj = nil ;
我发现dealloc
将约5秒后obj = nil;
运行,似乎是系统保留self
时发送的方法[self performSelectorInBackground:@selector(backgroundWork) withObject:nil] ;
和backgroundWork
返回后,该实例将被释放。
任何人都可以告诉我系统在这个背后做的工作。谢谢。
如果我改变'[self performSelectorInBackground:@selector(backgroundWork)withObject:nil]''self performSelector:@selector(backgroundWork)withObject:nil afterDelay:5]'并且'backgroundWork'方法中什么也不做,结果是一样的。所以我认为这不是主要原因。 – KudoCC 2014-10-20 07:01:36
@KudoCC' - [NSObject performSelector:withObject:afterDelay:]'直接保留接收器。在调用选择器之后,接收器通过'CFRunLoopTimerInvalidate'释放。所以我假设' - [NSObject performSelector:withObject:afterDelay:]'调度计时器来延迟方法调用。计时器保留目标。您可以通过禁用ARC,在'TestObj'中重载'-retain'和'-release'方法并在其中设置断点来轻松调查此问题。 (你可以运行这个https://gist.github.com/bartekchlebek/c36dba5d41bbe7b6fb5e) – 2014-10-20 07:13:16
听起来很合理,我会试一试,谢谢。 – KudoCC 2014-10-20 07:21:59