我正在使用Multipeer-Connectivity。
当会话结束时,应用程序进入主菜单,所有网络内容都会被释放,然后解除分配。
但我的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];
}
编辑:不,这绝对不是一个好的解决方案,因为它会让我的应用崩溃。无论如何,其他想法?
答案 0 :(得分:2)
当你调用[_session release]
,因为_session是一个Ivar,编译器将用[self->_session release]
替换这一行,并且该块将保留self
而不是iVar _session
。
这里有2个问题:
尝试保留正在解除分配的对象(self)。
当队列被执行时,它将调用已经解除分配的self。
以下解决方案创建一个局部变量,该变量指向与iVar相同的地址并将其释放到块内,该块不会捕获自身。
-(void) dealloc
{
//... other release
MCSession* localSession = _session;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[localSession release];
});
[super dealloc];
}
答案 1 :(得分:2)
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
对象的引用计数器的代码。