2011-05-28 25 views
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]; 
} 

}

+0

所以很遠,我發現的唯一修復方法是使用autorelease而不是release。至少,在4.0-4.3版本中可靠地工作。 – 2011-05-31 18:32:41

回答

0

您有過放你的代碼:

[currentSession disconnectFromAllPeers]; 
[currentSession setDelegate:nil]; 
[currentSession setDataReceiveHandler:nil withContext:nil]; 
[currentSession release]; // This is an over-release 
currentSession = nil; // You are trying to access a variable after it's been released 

您應該只釋放currentSession成員變量dealloc中,像這樣:

- (void)dealloc 
{ 
    [currentSession release]; 
    [super dealloc]; 
}