在多人连接中邀请对等方时偶尔崩溃

Posted

技术标签:

【中文标题】在多人连接中邀请对等方时偶尔崩溃【英文标题】:Occasional crash when inviting peer in multipeer connectivity 【发布时间】:2014-04-28 10:32:29 【问题描述】:

我有一个已发布的应用程序,它使用 Multipeer 连接定期发送少量数据。我正在使用 MCNearbyServiceAdvertiser 和 MCNearbyServiceBrowser。我测试时一切正常。但是,我收到了来自用户的崩溃报告,数量不多,但足以引起我的注意。

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -   [__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object from objects[2]'

Last Exception Backtrace:
0   CoreFoundation                       0x30b8cf03 __exceptionPreprocess + 131
1   libobjc.A.dylib                      0x3b321ce7 objc_exception_throw + 36
2   CoreFoundation                       0x30acad3f -[__NSPlaceholderDictionary initWithObjects:forKeys:count:] + 532
3   CoreFoundation                       0x30acab03 +[NSDictionary dictionaryWithObjects:forKeys:count:] + 48
4   MultipeerConnectivity                0x32420e87 -[MCNearbyServiceBrowser syncInvitePeer:toSession:withContext:timeout:] + 452
5   MultipeerConnectivity                0x324220cf __67-[MCNearbyServiceBrowser invitePeer:toSession:withContext:timeout:]_block_invoke + 84
6   libdispatch.dylib                    0x3b80ad53 _dispatch_call_block_and_release + 8
7   libdispatch.dylib                    0x3b80fcbd _dispatch_queue_drain + 486
8   libdispatch.dylib                    0x3b80cc6f _dispatch_queue_invoke + 40
9   libdispatch.dylib                    0x3b8105f1 _dispatch_root_queue_drain + 74
10  libdispatch.dylib                    0x3b8108dd _dispatch_worker_thread2 + 54
11  libsystem_pthread.dylib              0x3b93bc17 _pthread_wqthread + 296
12  libsystem_pthread.dylib              0x3b93badc start_wqthread + 6

尽管付出了很多努力,我还是无法重现崩溃。我曾尝试将应用程序置于后台,断开连接,打开和关闭网络等。通常一切都很好地重新连接,有时在点击“重新连接按钮”后,但没有崩溃。有没有人知道原因或至少如何迫使这种情况发生?

浏览器端是这样的:

-(void)setUpPP
  self.PPid = [[MCPeerID alloc] initWithDisplayName:@"PhotoFinish"];
  self.SSid = [[MCPeerID alloc] init];

  self.PPsession = [[MCSession alloc] initWithPeer:self.PPid securityIdentity:nil encryptionPreference:MCEncryptionNone];
  self.PPsession.delegate = self;

  self.PPbrowser = [[MCNearbyServiceBrowser alloc] initWithPeer:self.PPid serviceType:@"sprinttimer" ];
  self.PPbrowser.delegate = self;
  [self.PPbrowser startBrowsingForPeers];


-(IBAction)startSync:(id)sender 
  [self.PPbrowser invitePeer:self.SSid toSession:self.PPsession withContext:nil timeout:10];


-(void)session:(MCSession *)session peer:(MCPeerID *)peerID didChangeState:(MCSessionState)state

  NSString *displayString;
  if (state == MCSessionStateConnected && self.PPsession) 
    displayString=@"Start Sender connected";

   else if (state == MCSessionStateNotConnected && self.PPsession) 
    displayString=@"No Start Sender in range";
    connected=NO;
  
 [self performSelectorOnMainThread:@selector(displaySync:) withObject:displayString waitUntilDone:NO];


-(void)browser:(MCNearbyServiceBrowser *)browser foundPeer:(MCPeerID *)peerID withDiscoveryInfo:(NSDictionary *)info
  self.SSid=peerID;

【问题讨论】:

【参考方案1】:

知道什么动作触发startSync: 会很有帮助,但是在setUpPP 中,您将MCPeerID 的无意义实例(没有displayName)分配给self.SSid,所以我可以看到如果@ 会发生崩溃987654326@ 在self.SSid 获得真正的MCPeerID 分配给它之前被调用过。

我的建议是从self.SSid 作为 nil 开始,并确保您不发送邀请,除非该属性具有价值。更进一步,我不会依赖单个属性来存储 MCPeerID,它可能会在调用 startSync: 之前更改其值。

【讨论】:

感谢您的意见。您是对的,在获得值之前分配 SSid 并不理想。我会改变的。但是,问题(至少部分)似乎是设备连接到自身。因此,检查这一点并确保在失去连接时关闭会话似乎有所改善。虽然无法重现崩溃真的很令人沮丧,但我不得不猜测,发布更新并查看崩溃报告。

以上是关于在多人连接中邀请对等方时偶尔崩溃的主要内容,如果未能解决你的问题,请参考以下文章

如何正确拆除多人连接会话?

强制多人连接关闭

多对等连接:对等连接有时会失败:收到邀请响应,但我们从未向它发送邀请。中止

自定义视图控制器转换偶尔崩溃

应用程序启动时偶尔崩溃

升级到 TensorRT 7 后加载或构建 cuda 引擎偶尔会崩溃