GKGameSession- saveData 在 getShareURLWithCompletionHandler 之后总是失败并出现 malloc 错误

GKGameSession- saveData always fails with malloc error after getShareURLWithCompletionHandler

我正在尝试将 GKGameSession 合并到我的 Game Center 游戏中。我已经尝试了以下代码的几种组合:运行 异步命令,将它们链接到完成处理程序等。每次我看到相同的结果:我可以使用 saveData 就好了 直到我打电话给getShareURLWithCompletionHandler。之后,任何 saveData 的尝试都会引发错误。

这是出现问题的最简单代码版本:

CKContainer *defaultContainer = [CKContainer defaultContainer];
[GKGameSession createSessionInContainer:defaultContainer.containerIdentifier
                              withTitle:@"temp title"
                    maxConnectedPlayers:4
                      completionHandler:^(GKGameSession * _Nullable session, NSError * _Nullable error)
{
    if (error)
    {
        [self printError:error];
    }

    [session getShareURLWithCompletionHandler:^(NSURL * _Nullable url, NSError * _Nullable error)
    {
        if (error)
        {
            [self printError:error];
        }
    }];


    NSData *newData = [NSData dataWithBytesNoCopy:@"abcdefghijklmnopqrstuvwxyz" length:26];
    [reSession saveData:newData completionHandler:^(NSData * _Nullable conflictingData, NSError * _Nullable error)
    {
            if (error)
            {
                [self printError:error];
            }
    }];


}];

在大多数情况下,saveData 调用只会崩溃:

malloc: *** error for object 0x32df14: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug

但有时会报错:

GKGameSessionErrorDomain:GKGameSessionErrorUnknown

我尝试过保存不同类型的数据。我尝试通过链接完成处理程序中的所有调用来顺序调用。我试过在 creationSession 完成处理程序的内部和外部进行 URL 获取和数据保存。

我这里有什么地方做错了吗?

你应该把一个方块放在另一个里面。因为块可能以任何顺序完成。

我有这样的工作代码:

NSData *newData = [NSData dataWithBytesNoCopy:@"abcdefghijklmnopqrstuvwxyz" length:26];
[reSession saveData:newData completionHandler:^(NSData * _Nullable conflictingData, NSError * _Nullable error)
{
        if (error)
        {
            [self printError:error];
        } else {
[session getShareURLWithCompletionHandler:^(NSURL * _Nullable url, NSError * _Nullable error)
{
    if (error)
    {
        [self printError:error];
    }
}];

} }];

我也看到了同样的结果,但有一个更有用的错误:

The requested operation could not be completed because the session has been updated on the server, causing a conflict.

save 文档说,

It is up to the developer to decide how to handle save conflicts.

虽然在这里,每次重试保存都会永远失败。所以是的,这与您所处的状态相同。

然而,当加入游戏的玩家在他们的设备上输入 URL 时,他们的 GKGameSessionEventListenerdidAddPlayer: 被调用,然后如果他们保存...他们得到同样的冲突错误,但如果他们随后重试保存...它有效!

创建 link 的玩家无法保存或更新游戏状态,直到加入的玩家更新了数据。当其他玩家保存时,原始玩家会在 GKGameSessionEventListener 上调用 session:player:didSave:

此时原始玩家可以按预期保存。