2

我正在使用多点连接。

会话结束时,应用程序进入主菜单,所有网络内容都被释放,然后被释放。

但是我的 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];
}

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

4

2 回答 2

2

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

  1. 试图保留正在释放的对象(自身)。

  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];
}
于 2014-02-03T18:31:37.550 回答
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使用后台队列减少对象的引用计数器的代码。

于 2014-03-20T15:52:37.343 回答