Swift Fun c вызывается после ожидаемого - PullRequest
0 голосов
/ 02 августа 2020

У меня есть настройка кнопки, чтобы она сохраняла запись CK на основе выбора пользователя из другой части пользовательского интерфейса. После вызова функции CKRecord сохраняется в переменной. Следующая операция, которую должен выполнить код, - это развернуть эту переменную и использовать ее для редактирования и сохранения записи CK. Проблема заключается в том, что функция loadChallengeRecord (), которую я вызываю первой, не первая операция, выполняемая при нажатии кнопки. Вместо этого сначала запускается функция развертывания, из-за чего программа выходит из функции развертывания, потому что запись равна нулю, а затем с опозданием вызывается функция loadChallengeRecord (). Вот пример:

func loadChallengeRecord() {
    if let unwrapped = existingChallengeToDetails {
        recordID = CKRecord.ID(recordName: unwrapped, zoneID: zone)
        publicDatabase.fetch(withRecordID: recordID!) { (record, error) in
            if record != nil {
                self.currentChallenge = record
            } else {
                print("error fetching challenge record from server")
            }
        }
    }
}

@IBAction func btnVote(_ sender: Any) {
// load record and save it to var existingChallengeToDetails

loadChallengeRecord()

if let unwrapped = existingChallengeToDetails { }// edit and save record 
else { // error }

Что я делаю не так? Как я могу это исправить? Могу ли я указать приоритет выполнения этих функций?

Ответы [ 3 ]

0 голосов
/ 03 августа 2020

Самое простое решение - делать то, что вы должны делать в (асинхронном) обработчике завершения

func loadChallengeRecord() {
    guard let unwrapped = existingChallengeToDetails else { return }
    recordID = CKRecord.ID(recordName: unwrapped, zoneID: zone)
    publicDatabase.fetch(withRecordID: recordID!) { (record, error) in
        if let record = record {
            self.currentChallenge = record
            // edit and save record 
        } else {
            print("error fetching challenge record from server", error!)
        }
    }
}

@IBAction func btnVote(_ sender: Any) {
    // load record and save it to var existingChallengeToDetails
    loadChallengeRecord()
}
0 голосов
/ 03 сентября 2020

Два других ответа работали для конкретного случая c и работают по многим причинам, но это не совсем то, что я искал. Я продолжал сталкиваться с подобными проблемами, и после некоторых исследований я наконец нашел то, что искал: Семафоры

Вот базовое c объяснение:

func doSomething() {
  let semaphore = DispatchSemaphore(value: 0) // Setup the semaphore to value:0
  var x = 1
  var y = 2 
  if y != 0 {
    var sum = x + y
    semaphore.signal(). // Sends signal that code is complete
    // the code can continue from where semaphore.wait() is located. 
  } 

  semaphore.wait()  // Wait for semaphore.signal() to fire, then continue to return

  return sum // only after semaphore.signal() fires will this code run
}
0 голосов
/ 03 августа 2020

Напишите свою функцию с обработчиком завершения, как это

func loadChallengeRecord(completion:@escaping ()->Void) {
    if let unwrapped = existingChallengeToDetails {
        recordID = CKRecord.ID(recordName: unwrapped, zoneID: zone)
        publicDatabase.fetch(withRecordID: recordID!) { (record, error) in
            defer { completion }
            if record != nil {
                self.currentChallenge = record
            } else {
                print("error fetching challenge record from server")
            }
        }
    }
}

Используйте его так ... когда он возвращает завершение, вы можете делать другие вещи в зависимости от этого

loadChallengeRecord {
            
            // do your stuff here
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...