我正在使用多台面连接性。
会话结束时,应用程序进入主菜单,所有网络内容均已发布,然后汇总。
但是我的DealLoc方法在主线程中调用,MCSession
对象需要很长时间才能释放自己,我不知道为什么,因此主菜单屏幕冻结。
如果有人知道MCSession
为什么会这么长,我很感兴趣。但是,如果它来自McSession本身,这是一个很好的解决方案吗?
-(void) dealloc
{
//... other release
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[_session release];
_session = nil;
});
[super dealloc];
}
编辑: nope,这绝对不是一个好的解决方案,因为它会使我的应用程序崩溃。无论如何,其他想法?
当您致电[_session release]
时,由于_Session是IVAR,编译器将用[self->_session release]
替换此行,并且该块将保留self
而不是IVAR _session
。在这里,您有2个问题:
-
试图保留正在交易的对象(self)。
-
何时执行队列时,它将称为已被交易的自我。
以下解决方案创建一个局部变量,该变量指向与IVAR相同的地址并将其释放在块中,块将不会捕获自我。
-(void) dealloc
{
//... other release
MCSession* localSession = _session;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[localSession release];
});
[super dealloc];
}
bsarr007的解决方案将用于非ARC项目。如果您使用的是ARC,则可以尝试以下操作:
__block MCSession *localSession = _session;
_session = nil;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
oldSession = nil;
});
它对我有用。我在这里要做的是通过创建指向该对象的新局部变量来增加MCSession
对象的参考计数,因此在设置_session = nil
时不会立即对其进行处理。之后,我不同步使用背景队列降低MCSession
对象的参考计数器的代码。