2017-07-09 4 views
0

Dies könnte eine grundlegende Frage sein, aber ich kann das nicht herausfinden. Meine Funktion gibt immer einen Nullwert zurück und ich bin mir nicht sicher warum.Funktion gibt Nullwert zurück

Mein Hauptcode (in einem anderen Ansichtscontroller) ruft diese Funktion mit einer "Zeichenfolge" auf, um zu suchen. Aber am Ende der Funktion kann ich niemals die Ergebnisse zurückgeben. Wenn ich die Suchergebnisse dort drucke, wo ich die endgültige Druckanweisung habe, sehe ich die Ergebnisse. Aber unmittelbar nachdem diese Funktion abgeschlossen ist, ist der Rückgabewert gleich Null. Wie bekomme ich den Rückgabewert von dieser Funktion? Danke im Voraus,. Ich benutze Swift BTW.

func fetchSearchResults (_ searchString: String) -> Array<Any> { 
     self.globalPost = [Posts]() 
     self.postKeysArray = [] 
     var searchIndex:AlgoliaSearch.Index 
     let query = Query() 
     searchIndex = self.client.index(withName: "Comments") 

// können Sie all dies unten, bis die letzten paar Zeilen ...

 query.attributesToRetrieve = ["userComment","postId"] 
     query.attributesToHighlight = ["postId"] 
     query.query = searchString 
     query.optionalWords = [searchString] 

     let curSearchId = searchId 

     searchIndex.search(query, completionHandler: { (content, error) in 
      if (curSearchId <= self.displayedSearchId) || (error != nil) { 
       return // Newest query already displayed or error 
      } 
      self.displayedSearchId = curSearchId 
      self.loadedPage = 0 // Reset loaded page 

      guard let hits = content!["hits"] as? [[String: AnyObject]] else { return } 
      var tmp = [String]() 

      for hit in hits { 
       //    print ("Comment is \(commentRecord(json:hit).postId)") 
       tmp.append(commentRecord(json:hit).postId!) 
      } 
      self.postKeysArray = tmp 
      self.getDatafromFirebase(searchString) 

// so meine Suche Code gibt einige Werte hier ignorieren, und ich sehe sie in der Post keysArray.

  print ("Search Results -post keys is \(self.postKeysArray)") \\ returns correct values here in the Array 
     }) 
     self.searchId += 1 

// Aber hier bekomme ich einen NULL-Wert.

 return self.postKeysArray \\ returns empty array 

    } 
+2

Wenn Sie "null" sagen, meinen Sie "Null" oder ein leeres Array? Wenn es Letzteres ist, liegt das daran, dass es zurückkehrt, bevor der Beendigungshandler beendet ist. –

+0

Es ist ein leeres Array, aber ich bekomme die Ergebnisse für den Druck in der Completion-Handler. – SBCoder

+1

@SBCoder Es gibt nichts "Null" über ein leeres Array. – Alexander

Antwort

0

Als Alexander erwähnt, Sie drucken die Suchergebnisse innerhalb der Abschluss-Handler, die noch nicht ausgeführt hat, wenn fetchSearchResults zurückkehrt. Es gibt ein paar verschiedene Möglichkeiten, die Sie lösen könnten. Man wäre fetchSearchResults Refactoring einen Verschluss zu nehmen:

func fetchSearchResults (_ searchString: String, completionHandler completion: (Array<Any>) ->()) { 
    // ... 
    searchIndex.search(query, completionHandler: { (content, error) in 
     // ... 
     self.postKeysArray = tmp 
     self.getDatafromFirebase(searchString) 
     // so my search code returns some values here and i see them in the post keysArray. 

     print ("Search Results -post keys is \(self.postKeysArray)") \\ returns correct values here in the Array 
     completion(self.postKeysArray) 
    }) 
} 

Dann in Ihrem Haupt-Code ", wo immer Sie riefen:

let results = searchController.fetchSearchResults(searchString) 
doSomething(with: results) 

Sie würden jetzt haben:

searchController.fetchSearchResults(searchString, { results in 
    doSomething(results) 
}) 

Diese Zeile könnte auch geschrieben werden:

searchController.fetchSearchResults(searchString, doSomething) 

Wenn Sie wirklich nicht fetchSearchResults asynchron sein, dann könnten Sie DispatchSemaphore warten verwenden, bis der Abschluss-Handler beendet hat: dass

func fetchSearchResults (_ searchString: String) -> Array<Any> { 
    // ... 
    var semaphore = DispatchSemaphore(0) 
    searchIndex.search(query, completionHandler: { (content, error) in 
     // ... 
     self.postKeysArray = tmp 
     self.getDatafromFirebase(searchString) 
     // so my search code returns some values here and i see them in the post keysArray. 

     print ("Search Results -post keys is \(self.postKeysArray)") \\ returns correct values here in the Array 
     semaphore.signal() 
    }) 
    semaphore.wait() 
    return self.postKeysArray 
} 

Hinweis, wenn Sie wissen, was Sie tun, Semaphoren ist nicht eine gute Idee. Wenn Sie nicht wissen, mit welchen Threads verschiedene Callbacks aufgerufen werden können, kann dies zu einem Deadlock führen. Das obige Beispiel funktioniert nicht, wenn der Beendigungshandler searchIndex.search unter DispatchQueue als fetchSearchResults aufgerufen wird. Wenn du nicht verstehst, worüber ich spreche, solltest du es wahrscheinlich nicht tun. Es wird fast sicher besser sein, asynchrone Rückrufe zu verwenden.

+0

Vielen Dank dafür. Ich habe es mit Ihrem empfohlenen Code arbeiten. Ich brauche etwas Zeit, um es zu verstehen, aber vielen Dank noch einmal. Übrigens, gibt es eine E-Mail/Twitter, bei der ich dich erreichen könnte? – SBCoder

+0

Ich sollte eine Email auf meinem GitHub @jumhyn haben. – Jumhyn

Verwandte Themen