0
當我調用displayNameForPeer給另一個對象(而不是自己)之後釋放GKSession時,我可以可靠地使模擬器崩潰,我不確定它是否是我做錯了或者它是Apple的Gamekit框架的錯誤(我是否需要擔心它,因爲我只能看到4.0和4.1下的崩潰,而不是4.2+)。GKSession displayNameForPeer可以防止釋放會話(iOS 4.0,4.1)
輸出是:
found available peer; checking name and ID... m4, 26176566
*** -[GKSessionInternal lock]: message sent to deallocated instance 0x7508900
這裏是最小的可重複的代碼集 - 請注意,另一個GKSession必須是在網絡上可見(這樣有發現調用displayNameForPeer上可用的同行)來觸發崩潰。在另一臺設備上運行相同的代碼,但沒有makeUnavailable和killSession調用就足夠了。
- (void)viewDidLoad
{
[self createSession];
[self makeAvailable];
peerListAvailable = [[NSMutableArray alloc] initWithArray:[currentSession peersWithConnectionState:GKPeerStateAvailable]];
for (NSString *peer in peerListAvailable)
{
// this method guarantees the crash on session release
NSLog(@"found available peer; checking name and ID... %@, %@",[currentSession displayNameForPeer:peer], peer);
}
[peerListAvailable release];
peerListAvailable = nil;
[self makeUnavailable];
[self killSession];
[super viewDidLoad];
}
- (void) createSession
{
if (!currentSession)
{
currentSession = [[GKSession alloc] initWithSessionID:@"GKTester" displayName:nil sessionMode:GKSessionModePeer];
currentSession.delegate = self;
currentSession.disconnectTimeout = 30;
[currentSession setDataReceiveHandler: self withContext:nil];
}
}
-(void) killSession
{
if (currentSession)
{
[currentSession disconnectFromAllPeers];
[currentSession setDelegate:nil];
[currentSession setDataReceiveHandler:nil withContext:nil];
[currentSession release]; // crash occurs after this
currentSession = nil;
}
}
-(void) makeAvailable
{
while (currentSession && !currentSession.available)
{
[currentSession setAvailable:YES];
[NSThread sleepForTimeInterval:.5];
}
}
-(void) makeUnavailable
{
while (currentSession && currentSession.available)
{
[NSThread sleepForTimeInterval:.5];
[currentSession setAvailable:NO];
}
}
所以很遠,我發現的唯一修復方法是使用autorelease而不是release。至少,在4.0-4.3版本中可靠地工作。 – 2011-05-31 18:32:41