发送消息时会自我保留

时间:2014-10-20 06:32:02

标签: ios objective-c

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

我分配并初始化实例并发送doSomethingInBackground消息并为其分配nil,以便尽快释放它。

TestObj *obj = [[TestObj alloc] init] ;
[obj doSomethingInBackground] ;
obj = nil ;

我发现dealloc将在约5秒obj = nil;后运行,系统似乎在向self方法[self performSelectorInBackground:@selector(backgroundWork) withObject:nil] ;发送backgroundWork之后{{1}}返回后,实例将被释放。

任何人都可以告诉我系统背后的工作。感谢。

3 个答案:

答案 0 :(得分:2)

引擎下的{p> -[NSObject performSelectorInBackground:withObject:]调用-[NSThread initWithTarget:selector:object:],它会保留原始接收者(此处作为target参数传递)

NSThread文档:"在执行分离线程期间保留对象target和argument。它们在线程最终退出时被释放。"

答案 1 :(得分:2)

来自文档,

performSelectorInBackground:withObject:方法创建一个新的分离线程,并使用指定的方法作为新线程的入口点。例如,如果你有一个对象(由变量myObj表示)并且该对象有一个你想在后台线程中运行的doSomething方法,你可以使用以下代码来做到这一点:

[myObj performSelectorInBackground:@selector(doSomething) withObject:nil];

调用此方法的效果与使用当前对象,选择器和参数对象作为参数调用detachNewThreadSelector:toTarget:withObject: NSThread方法的效果相同。使用默认配置立即生成新线程并开始运行。

在detachNewThreadSelector中:toTarget:withObject:documentation,

  

执行期间保留对象aTarget和anArgument   分离的线程,然后释放。退出已分离的线程   aTarget完成后立即(使用exit类方法)   执行aSelector方法。

关于performSelector:AfterDelay:,

  

此方法设置一个计时器来执行aSelector消息   当前线程的运行循环。计时器配置为在。中运行   默认模式(NSDefaultRunLoopMode)。当计时器触发时,线程   尝试从运行循环中取消消息并执行   选择。如果运行循环正在运行并且在默认情况下,它会成功   模式;否则,计时器等待直到运行循环处于默认状态   模式

并且

  

计时器保持对该对象的强引用,直到它为止   计时器)无效。

如果您不希望保留Obj,可以使用弱引用对象

 TestObj *obj = [[TestObj alloc] init] ;
 __weak typeof(obj) weakObj = obj;
 [weakObj doSomethingInBackground] ;
 obj = nil ;

答案 2 :(得分:1)

虽然在其他答案中已经讨论过像performSelector:这样的特殊情况,但我认为将答案添加到一般情况中是有帮助的:

  

向其发送消息时会自我保留

没有。在两个手动保留计数和ARC self中永远不会隐式保留。在方法执行期间,必须注意不要释放消息的接收者。

虽然ARC self的类型很强,但实际上并未保留该对象。请参阅ARC documentation