开发者

GKSession displayNameForPeer prevents releasing the session (iOS 4.0, 4.1)

I can reliably crash the simulator with this when releasing the GKSession after calling displayNameForP开发者_StackOverflow中文版eer for another peer (not self), and I'm not sure if it's something I'm doing wrong or if it's a bug with Apple's Gamekit framework (and whether I need to worry about it, since I only see the crash under 4.0 and 4.1, not 4.2+).

The output is:

found available peer; checking name and ID... m4, 26176566
*** -[GKSessionInternal lock]: message sent to deallocated instance 0x7508900

Here's the minimal reproducible code set -- note that another GKSession must be visible on the network (so that there's an available peer found to call displayNameForPeer on) to trigger the crash. Running this same code on another device but without the makeUnavailable and killSession calls is adequate.

- (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];
}

}


You have an over-release in your code:

[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

You should release the currentSession member variable in dealloc only, like so:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜