我用蓝牙模式制作了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本身有关。我在此视图中设置了其他警报视图。
我希望你们能帮帮我。
提前致谢。
答案 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也不例外(虽然它通常令人惊讶地宽容)。