接受传入请求时Gamekit API错误

时间:2012-07-10 15:49:37

标签: iphone xcode ipad gamekit gkpeerpickercontroller

我用蓝牙模式制作了iPhone游戏,你可以通过蓝牙播放1对1。我对选择器的实现如下:

picker = [[GKPeerPickerController alloc] init];
picker.delegate = self;
picker.connectionTypesMask = GKPeerPickerConnectionTypeNearby;
[picker show];

我不知道哪个代码会出错,所以我也会粘贴我的代码以用于与选择器有关的所有其他方法:

- (void) receiveData:(NSData *)data fromPeer:(NSString *)peer inSession: (GKSession *)session context:(void *)context {
  NSString *dataString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
  NSDictionary *dataDictionary = [NSDictionary dictionaryWithObjects: [NSArray arrayWithObjects:dataString, peer, session, nil] forKeys:[NSArray arrayWithObjects:@"data", @"peer", @"session", nil]];
  [dataString release];
  [self performSelectorOnMainThread:@selector(receivedData:) withObject:dataDictionary waitUntilDone:YES];
}
- (GKSession *)peerPickerController:(GKPeerPickerController *)picker
    sessionForConnectionType:(GKPeerPickerConnectionType)type {
  // Create a new session if one does not already exist
    if (!self.currentSession) {
      self.currentSession = [[[GKSession alloc] initWithSessionID:@"Session" displayName:nil sessionMode:GKSessionModePeer] autorelease];
      self.currentSession.delegate = self;
    }
    return self.currentSession;
  }
  -(void)peerPickerController:(GKPeerPickerController *)pk didConnectPeer:(NSString *)peerID toSession:(GKSession *)session {
    self.currentSession = session;
    session.delegate = self;
    [session setDataReceiveHandler:self withContext:nil];
    picker.delegate = nil;
    [picker dismiss];
    [picker autorelease];
  }
  -(void)peerPickerControllerDidCancel:(GKPeerPickerController *)pk {
    picker.delegate = nil;
    [picker autorelease];
    [self.navigationController popViewControllerAnimated:YES];
  }
  // FAIL
  - (void)session:(GKSession *)session didFailWithError:(NSError *)error {
    NSLog(@"error : %@", [error description]);
  }
  // SESSION VIND ANDERE SESSION -> CONNECT
  -(void)session:(GKSession *)session peer:(NSString *)peerID didChangeState:(GKPeerConnectionState)state {
    switch (state) {
      case GKPeerStateConnected:
        NSLog(@"connect met peer %@", [currentSession displayNameForPeer:peerID]);
        [self generateRandomNumberAndSendIt];
        break;
      case GKPeerStateDisconnected:
        NSLog(@"disconnected");
        [self.currentSession disconnectFromAllPeers];
        currentSession = nil;
        [self.navigationController popViewControllerAnimated:YES];
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Whoopsie" message:@"The connection failed" delegate:nil cancelButtonTitle:@"Okido" otherButtonTitles:nil];
        [alert show];
        [alert release];
        [super viewDidDisappear:YES];
        break;
      }
    }

有时当我接受传入请求时,选择器会在一台设备上自行删除,而在另一台设备上我会收到错误:wait_fences: failed to receive reply: 10004003。我认为它与alertview本身有关。我在此视图中设置了其他警报视图。

我希望你们能帮帮我。

提前致谢。

2 个答案:

答案 0 :(得分:1)

您需要设置一些断点并调试代码崩溃的位置,任何人都无法确定代码崩溃的位置,我们能做的最好的事情就是通过指出代码中的奇怪来猜测。该错误可能甚至不在您提供的代码中。

正如其他人所提到的,你绝对不应该在非[super viewDidDisappear:YES];方法中使用viewDidAppear:语句。

我也猜测,如果你正在调试,那么控制台中的错误消息比wait_fences: failed to receive reply: 10004003更有用。确保已在所有异常上启用断点。如果你不知道如何做到这一点,here are some instructions。逐步执行异常,找出它所在的行,并找出抛出的错误。

您的[picker autorelease];电话也有点奇怪。如果您想自动发布选择器,只需执行picker = [[[GKPeerPickerController alloc] init] autorelease];。将自动释放语句放在GameKit委托方法中是很奇怪的。

答案 1 :(得分:1)

尝试将UIAlertView调用包装在块中以在主线程上调用,例如

dispatch_async(dispatch_get_main_queue(), ^{
   // Show UIAlertView
}

虽然我以前没有像这样使用GK,但我猜它(像许多基于网络的库一样)可以触发来自主GUI线程以外的其他线程的回调。在大多数GUI库中,从主GUI线程以外呈现甚至操纵用户界面是一个很大的禁忌,而Cocoa也不例外(虽然它通常令人惊讶地宽容)。