GKGameSession- saveData всегда завершается с ошибкой malloc после 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

Я пробовал разные виды сохраняемых данных. Я попытался сделать вызовы последовательными, связав все вызовы в обработчиках завершения. Я попытался сделать выборку URL и сохранить данные внутри и снаружи обработчика завершения creationSession.

Я что-то здесь не так делаю?

2 ответа

Решение

Я вижу то же самое, но с более полезной ошибкой:

Запрошенная операция не может быть завершена, поскольку сеанс был обновлен на сервере, что вызвало конфликт.

save документация говорит,

Разработчик должен решить, как обрабатывать конфликты сохранения.

Здесь, однако, повторная попытка сохранения завершается неудачей каждый раз, навсегда. Так что да, это то же самое состояние, в котором вы находитесь.

Однако, когда игрок, присоединяющийся к игре, вводит URL на своем устройстве, его GKGameSessionEventListener"s didAddPlayer: вызывается, и затем, если они сохраняются... они получают ту же ошибку конфликта, но если они затем повторяют попытку сохранения... это работает!

Игрок, создавший ссылку, заблокирован для сохранения или обновления состояния игры, пока присоединяющиеся игроки не обновят данные. Когда другой игрок спасает, оригинальный игрок получает вызов session:player:didSave: на GKGameSessionEventListener,

В этот момент первоначальный игрок может сохранить как ожидалось.

Вы должны положить один блок внутри другого. Потому что блоки могут быть завершены в любом порядке.

У меня есть рабочий код, как это:

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

}}];

Другие вопросы по тегам