【问题标题】:Function returns null value函数返回空值
【发布时间】:2017-07-09 22:37:47
【问题描述】:

这可能是一个基本问题,但我无法弄清楚。我的函数总是返回一个空值,我不知道为什么。

我的主要代码(在不同的视图控制器中)使用“字符串”调用此函数进行搜索。但是在函数结束时,我永远无法返回结果。如果我在有最终打印语句的地方打印搜索结果,那么我确实会看到结果。但是在该函数完成后,返回值为零。我如何从这个函数中获得返回值?提前致谢,。顺便说一句,我正在使用 Swift。

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

// 您可以忽略下面的所有内容,直到最后几行...

        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)

// 所以我的搜索代码在这里返回了一些值,我在帖子的 keysArray 中看到了它们。

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

// 但是这里我得到一个 NULL 值。

        return self.postKeysArray \\ returns empty array

    }

【问题讨论】:

  • 当您说“null”时,您是指nil 还是一个空数组?如果是后者,那是因为它在完成处理程序完成之前返回。
  • 它是一个空数组,但我确实得到了完成处理程序中的打印结果。
  • @SBCoder 没有关于空数组的“null”。
  • @SBCoder 它是空的,因为您在完成添加竞争处理程序之前返回数组

标签: swift function return-value


【解决方案1】:

正如 Alexander 所指出的,您正在完成处理程序中打印搜索结果,当 fetchSearchResults 返回时,该处理程序尚未执行。有几种不同的方法可以解决这个问题。一种是重构 fetchSearchResults 以关闭:

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)
    })
}

然后,在您的“主代码”中,无论您在哪里调用:

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

你现在有:

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

这一行也可以写成:

searchController.fetchSearchResults(searchString, doSomething)

如果你真的不能让 fetchSearchResults 异步,那么你可以使用DispatchSemaphore 等待完成处理程序完成:

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
}

请注意,除非您知道自己在做什么,否则使用信号量不是一个好主意。如果您不知道哪些线程可能会调用各种回调,则可能会导致死锁。如果在与fetchSearchResults 相同的DispatchQueue 上调用searchIndex.search 完成处理程序,则上述示例将不起作用。如果你不明白我在说什么,你可能不应该这样做。使用异步回调几乎肯定会更好。

【讨论】:

  • 非常感谢您。我让它与您推荐的代码一起使用。需要一些时间来理解它,但再次感谢。顺便说一句,我可以通过电子邮件/推特联系到您吗?
  • 我的 GitHub @jumhyn 上应该有一封电子邮件。
猜你喜欢
  • 2020-08-17
  • 1970-01-01
  • 1970-01-01
  • 2020-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多