McSession花了很长时间才能进行DealLoc



我正在使用多台面连接性。

会话结束时,应用程序进入主菜单,所有网络内容均已发布,然后汇总。

但是我的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个问题:

  1. 试图保留正在交易的对象(self)。

  2. 何时执行队列时,它将称为已被交易的自我。

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

最新更新