Случайный сбой при приглашении пира в многопользовательском соединении

У меня есть опубликованное приложение, которое использует функцию многопользовательского режима для регулярной отправки небольших объемов данных. Я использую 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 так что я мог видеть, что происходит сбой, если startSync: когда-либо звонил раньше self.SSid получает настоящий MCPeerID назначен на это.

Мое предложение будет начинаться с self.SSid как ноль, и убедитесь, что вы не отправляете приглашения, если это свойство не имеет значения. Идя дальше, я бы не стал полагаться на одно свойство для хранения MCPeerID что могло бы изменить его значение раньше startSync: называется.

Другие вопросы по тегам