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