GKSession displayNameForPeer 阻止释放会话(iOS 4.0、4.1)
在为另一个对等点(不是自己)调用 displayNameForPeer 后释放 GKSession 时,我可以可靠地使模拟器崩溃,并且我不确定这是否是我做错的事情,或者是否是 Apple Gamekit 框架的错误(以及我是否需要担心它,因为我只看到 4.0 和 4.1 下的崩溃,而不是 4.2+ 下的崩溃)。
输出是:
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];
}
}
I can reliably crash the simulator with this when releasing the GKSession after calling displayNameForPeer 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];
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您的代码中存在过度释放:
您应该仅在 dealloc 中释放 currentSession 成员变量,如下所示:
You have an over-release in your code:
You should release the currentSession member variable in dealloc only, like so: