MCSession需要很长时间才能解除分配

时间:2014-01-31 15:33:35

标签: ios multipeer-connectivity mcsession

我正在使用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];
}

编辑:不,这绝对不是一个好的解决方案,因为它会让我的应用崩溃。无论如何,其他想法?

2 个答案:

答案 0 :(得分:2)

当你调用[_session release],因为_session是一个Ivar,编译器将用[self->_session release]替换这一行,并且该块将保留self而不是iVar _session。 这里有2个问题:

  1. 尝试保留正在解除分配的对象(self)。

  2. 当队列被执行时,它将调用已经解除分配的self。

  3. 以下解决方案创建一个局部变量,该变量指向与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对象的引用计数器的代码。